Professional Documents
Culture Documents
La ejecución dinámica de instrucciones SQL es algo a lo que tarde o temprano (más bien
temprano) tenemos que enfrentarnos. Y ya que tenemos que hacerlo más vale saber como
funciona y tener un poco de cuidado…
¡No podemos utilizar variables en cualquier parte de una sentencia! Por ejemplo no podemos
utilizarlas en la cláusula FROM.
Como vemos es sencillo, pero utilizar el SQL así dentro de un procedimiento almacenado nos
ocasiona dos problemas.
En primer lugar utilizar así los parámetros da lugar a problemas de seguridad porque estamos
permitiendo que el usuario utilice trucos de inyección de código y que nuestro procedimiento
almacenado haga cosas para las que no fue creado.
Un ejemplo de lo que alguien podría llegar a hacer es:
Que un usuario pueda ejecutar sentencias como esta no es algo muy deseable verdad.
El segundo problema que nos plantea el uso de EXEC es de rendimiento. Como ya sabemos
una de las ventajas de los procedimientos almacenados es que cuando se ejecuta la primera vez
se compila, y no es necesario recompilarlo en ejecuciones sucesivas. Pero esto deja de ser
cierto cuando usamos EXEC para ejecutar SQL dinámico porque cada ejecución requiere una
compilación.
Esto nos lleva al segundo modo de ejecutar SQL dinámico dentro de un procedimiento
almacenado.
SP_EXECUTESQL
Usar este procedimiento almacenado soluciona en gran parte los dos problemas que veíamos
con la ejecución dinámica a través de EXEC.
Por un lado lo único que se transmite a sp_executesql son los parámetros y eso evita la
inyección de código, y por otro lado se puede reutilizar el plan de ejecución.
Veamos un ejemplo de cómo utilizar este procedimiento.
USE NorthWind
DECLARE @sSQL nvarchar(1000)
--la variabla que contiene la cadena a ejecutar debe ser unicode, por eso lo de nvarchar
SET @sSQL = ' SELECT * FROM Products WHERE ProductName = @NombreProducto'
EXEC sp_executesql @sSQL, N' @NombreProducto nvarchar(50)' , @NombreProducto = ' chai'
Como vemos el primer parámetro es la sentencia que queremos ejecutar, después viene
declarada la variable que vamos a usar y por último le damos valor a esa variable.
Seguro que se os ocurren un par de utilidades para sp_executesql.
En cuanto a los permisos recordar algo muy importante. La sentencia SQL se ejecuta dentro del
contexto de seguridad del usuario, no del procedimiento que llama a esa sentencia.
Cierto que es un poco más complicado (se utiliza la función CASE), pero no hay inyección de
código posible y una vez calculado el plan de ejecución se utilizará sin recompilar una y otra vez
Como conclusión nos queda que el SQL dinámico es una herramienta potente pero peligrosa si
no se trata con cuidado, y que la mayoría de las veces no necesitamos recurrir a ella porque
siempre podemos encontrar otra solución.
César Manivesa
sql@manivesa.com
http://sql.manivesa.com