Ver Mensaje Individual
  #1  
Antiguo 30-06-2006
Avatar de marcoszorrilla
marcoszorrilla marcoszorrilla is offline
Capo
 
Registrado: may 2003
Ubicación: Cantabria - España
Posts: 11.221
Reputación: 10
marcoszorrilla Va por buen camino
La dirección, idiota, la dirección...

El SQL Server de Microsoft no deja de sorprenderme día a día ... casi siempre de forma
// desagradable. Cuando pensaba que ya no podía encontrar más pretextos para no utilizarlo,
// he aquí que Microsoft saca un as de la manga y te das cuenta de cuánto puedes odiar a
// alguien o algo. Qué tristeza, he perdido la poca fé que me quedaba en la naturaleza humana.

// Al grano. Para producir el desastre vale lo mismo la versión 6, que la 6.5, la 7 y
// sospecho que cuando haya una 8, igual. Cree un procedimiento idiota como el siguiente,
// utilizando SQL Explorer o el SQL Query Tool (rebautizado como SQL Query Analizer
// en la 7; es como cuando llegas a tu casa de madrugada tras una juerga, no enciendes la
// luz y los dedos de tus pies descubren que alguien ha cambiado los muebles de lugar):

create procedure ExtremaImbecilidad
@a integer, @b integer, @c integer output as
select @c = @a + @b

// Se supone que esta joya de la programación recibe tres parámetros. Los dos primeros son
// parámetros de entrada; el procedimiento los suma y coloca el resultado en el tercer
// parámetro, que ha sido declarado como un parámetro de salida.

// ¡Pobre de mí! Yo pensaba que podía utilizar el procedimiento anterior desde otro
// procedimiento de esta simple manera:

create procedure OtraIdiotez @v1 integer, @v2 integer as
begin
// Declaración de variables locales
declare @resultado integer
// Llamamos al procedimiento
execute ExtremaImbecilidad @v1, @v2, @resultado
// Mostrar el resultado en la consola de SQL Server
select 'El resultado es: ', @resultado
end

// Ahora llame al último procedimiento directamente:

execute OtraIdiotez 1, 2

// ¿Sabe qué valor se muestra en pantalla? ¡Nulo, amigo mío, en vez de 3! La variable
// @resultado no recibe el valor asignado al parámetro de salida @c, durante la llamada
// interna a ExtremaImbecilidad.

// Para aquellos que no están familiarizados con Transact SQL, es necesario saber que la
// instrucción select puede utilizarse en dos contextos muy diferentes en este dialecto.
// Dentro de ExtremaImbecilidad, cada valor mencionado en la cláusula se asigna a una variable
// local. Este es el equivalente al select/into de Oracle e InterBase. El ejemplo utilizado
// en OtraIdiotez, sin embargo, no tiene equivalente directo en estos sistemas. Si no hay
// variables a las que asignar los valores del select, dichos valores se muestran en la propia
// ventana de SQL Query Analizer, o se ignoran en caso contrario. Esta es una técnica bastante
// primitiva para depurar procedimientos almacenados. Pero también se utilizan los select libres
// para programar procedimientos de selección en Transact SQL: procedimientos que devuelven un
// conjunto de filas como resultado.

// La explicación: el tonto compilador de TransactSQL no verifica los prototipos de los
// procedimientos que llamamos (muy en el estilo de una gente capaz de alumbrar un Visual Basic).
// Cuando pasamos @resultado, el compilador lo acepta alegremente y mete en la pila el valor
// de la variable, cuando lo que hace falte meter es su dirección:

execute ExtremaImbecilidad @v1, @v2, @resultado output

// La palabra reservada output funciona en este caso como un operador de referencia, que toma
// la dirección de la variable precedente y la introduce en la pila.

// ¿Por qué no había tropezado antes con este problema? Sencillamente porque (gracias a Dios)
// nunca había tenido que desarrollar ningún programa realmente grande con SQL Server. Y
// siempre que había programado un procedimiento almacenado con parámetros de salida, terminaba
// llamando al procedimiento desde Delphi o C++ Builder. De hecho, podía haberme imaginado lo
// que estaba sucediendo. ¿Se ha dado cuenta de que Delphi es incapaz de adivinar si los
// parámetros de un procedimiento almacenado de SQL Server son de entrada o de salida? Al
// parecer, esta información no está disponible en el catálogo de la base de datos.

// Por este motivo, desde ayer un post-it adorna mi monitor, con un gran mensaje en letras
// rojas sobre fondo amarillo:

// ¡La dirección, idiota, no te olvides de pasar la dirección!
Responder Con Cita