Hola Pablo, veo que no has leido el articulo ;) te paso un fragmento
del mismo con respecto a este tema:
EXEC() y sp_executesql
En el SQL Server, el SQL dinámico de ejecuta con EXEC() o sp_executesql.
EXEC()
Utilizar EXEC() es la manera más sencilla de ejecutar SQL dinámico:
SELECT @tabla = 'ventas' + @año + @mes
EXEC('SELECT * FROM ' + @tabla)
Puede que este ejemplo te parezca extremadamente básico, pero quiero
destacar unos puntos importantes. Primero, son los permisos del
usuario actual que están en vigor al ejecutar la instrucción, incluso
cuando la instrucción se halla dentro de un procedimiento almacenado.
Segundo, EXEC() es similar al EXEC que se utiliza para ejecutar un
procedimiento almacenado, pero ejecuta un lote de instrucciones SQL en
lugar de un procedimiento almacenado. Sin embargo, en ambos casos el
lote SQL - o procedimiento almacenado - se ejecuta en otro alcance del
procedimiento que lo ejecutó, pues hay que notar los puntos
siguientes:
Dentro del lote SQL no tienes acceso a las variables locales o a los
parámetros del procedimiento almacenado externo
Si usas USE en el lote SQL, esto no afecta al procedimiento almacenado externo
Si creas tablas temporales en el lote SQL se quitan al acabar el lote
- como si fuera un procedimiento almacenado - pues no las puedes
utilizar en el procedimiento almacenado externo. Sin embargo, el lote
SQL tiene acceso a las tablas temporales creadas en el procedimiento
almacenado externo.
Si cambias las opciones SET en el lote SQL, esto no afecta al
procedimiento almacenado externo
El plan de consultas para el lote SQL no es parte del plan de
consultas para el procedimiento almacenado externo. En cuanto a la
caché, el lote SQL es igual a una consulta de SQL ad hoc enviada desde
el cliente.
Si sale un error que termina el lote - por ejemplo un rollback en un
desencadenador - se termina el lote, pero también el procedimiento
almacenado externo, y el procedimiento almacenado que lo ejecutó, y
así...
A diferencia de la ejecución de un procedimiento almacenado, no puedes
utilizar parámetros, y tampoco existe un valor del estado de retorno.
El valor de @@ERROR depende de la última instrucción en el lote SQL,
pues si hay un error en el lote pero luego una instrucción que se
ejecuta sin error, @@ERROR tendrá el valor 0.
EXEC() existe desde el SQL Server 6.0.
Nota que EXEC(@sql) no tiene nada que ver con EXEC @sp, lo que ejecuta
un procedimiento almacenado cuyo nombre es el valor de @sp.
sp_executesql
sp_executesql existe desde el SQL Server 7, y lleva la ventaja que
admite el uso de parámetros de entrada y salida con la cadena de SQL
dinámico. El ejemplo siguiente demuestra el uso de un parámetro de
salida:
DECLARE @sql nvarchar(4000), -- nvarchar(MAX) en SQL 2005.
@col sysname,
@min varchar(20)
SELECT @col = N'au_fname'
SELECT @sql = N'SELECT @min = convert(varchar(20), MIN(' + @col +
N')) FROM authors'
EXEC sp_executesql @sql, N'@min varchar(20) OUTPUT', @min OUTPUT
SELECT @min
Ya ves que es mucho más fácil asignar un valor de tu instrucción de
SQL dinámico a una variable local con sp_executesql que con EXEC() -
lo puedes hacer mediante una instrucción INSERT EXEC(), pero no es una
solución muy cómoda -.
El primer parámetro para sp_executesql es una instrucción SQL. El tipo
de datos del parámetro es ntext, pues tienes que utilizar una variable
de tipo nvarchar - ya que no se admite la declaración de parámetros
ntext -. Si tu instrucción es una cadena literal, pon N antes de la
comilla simple para indicar una cadena Unicode. La sentencia puede
incluir parámetros que empiezan con una arroba - @ - y que no están
relacionados con las variables en al alcance actual. La instrucción
SQL es como todas las demás, es decir que los parámetros se admiten
únicamente donde la sintaxis SQL los permite. O sea, no puedes
utilizar parámetros para los nombres de tablas o columnas , pues si
los determinas dinámicamente, tienes que incluirlos en la cadena que
será ejecutada.
El segundo parámetro para sp_executesql es un listado de declaraciones
de variables en la forma habitual, incluyendo parámetros de salida y
valores predeterminados - parece que el tema de los parámetros de
salida no está en los Books Online del SQL Server -. El listado es de
tipo ntexttambién, y debe incluir todas las variables utilizadas en la
sentencia SQL.
Los demás parámetros para sp_executesql son los que has declarado en
el listado de parámetros, en el mismo orden - o puedes escribir los
nombres explícitamente -.
sp_executesql suele ser más útil que EXEC() por varios motivos.
Utilizando el sp_executesql no tienes que contar con la
autoparametrización de SQL Server, ya que tú suministras los
parámetros. Así, es más probable que el SQL Server utilice un plan de
consultas que ya existe en la caché - aunque las diferencias en el
espacio en blanco todavía pueden impedir esto -. Hablaré de las otras
ventajas de sp_executesql en mi análisis de inyección del SQL y las
buenas prácticas de código.
Los puntos que destaqué en la sección sobre EXEC() también se aplican
en el caso de sp_executesql:
El lote SQL está en su propio alcance, y no tienes acceso a las
variables en el procedimiento almacenado exterior
Los permisos del usuario actual se aplican
El uso de USE no afecta al procedimiento almacenado exterior
Tablas temporales creadas por el lote SQL no están accesibles desde el
procedimiento almacenado exterior
El uso de opciones SET afecta únicamente al lote SQL
Si el lote ejecutado por sp_executesql se termina debido a un error,
el procedimiento almacenado exterior también se termina
El valor de @@ERROR indica el estatus de la última sentencia en el lote SQL
Según dice Books Online, el valor del estado de retorno de
sp_executesql puede ser 0 - éxito - o 1 - fallo -. Pero parece que en
realidad, el valor del estado de retorno es el valor de @@ERROR, por
lo menos en el SQL Server 2000.
Consulta Books Online para tener todos los detalles sobre
sp_executesql. Mira también el artículo 262499 en el Microsoft
Knowledge Base, donde se explica el uso de parámetros OUTPUT.
Qué método utilizar
Si utilizas el SQL dinámico frecuentemente, pues sp_executesql sería
mejor porque el SQL Server puede utilizar el plan de consultas en la
caché, y también gozas del uso de parámetros. Claro que no lo puedes
utilizar si sigues trabajando con la versión el SQL Server 6.5, pero
tampoco es posible si tu sentencia SQL es demasiado larga para una
variable nvarchar(4000). EXEC() permite concatenar cadenas:
-----------------------------------------------------------
Microsoft MVP en SQL Server
Mentor asociado en SQLTotalConsulting
(excelencia en servicios y consultoria SQLServer)
Orador Culminis - Microsoft Influencier
www.sqltotalconsulting.com
-----------------------------------------------------------
El 7/06/07, Pablo A. Allois <[EMAIL PROTECTED]> escribió:
Maxi,
Que diferencia hay entre el EXEC y sp_executesql ?
Saludos!