El SQL dinámico y los procedimientos almacenados son dos de los componentes más importantes de SQL Server. En este artículo, veremos las ventajas y desventajas de cada uno de ellos y cuándo usarlos.
Rendimiento
Todo el mundo sabe la respuesta a esta pregunta. Los procedimientos almacenados superan al SQL dinámico en términos de rendimiento. Un procedimiento almacenado se almacena en caché en la memoria del servidor y su ejecución es mucho más rápida que SQL dinámico. Si todas las variables restantes se mantienen constantes, el procedimiento almacenado supera al SQL dinámico.
Separación de preocupaciones
En términos de separación de preocupaciones, los procedimientos almacenados superan sin duda alguna al SQL dinámico.
Los procedimientos almacenados le permiten mantener la lógica de su base de datos separada de su lógica comercial. Por lo tanto, si ocurre un error en su lógica de negocios, solo tiene que cambiar el código de su aplicación. Por el contrario, si hay un problema con la lógica de la base de datos, solo se debe modificar el procedimiento almacenado. Además, si se actualiza un procedimiento almacenado, no es necesario volver a compilar ni implementar el código de la aplicación.
Si utiliza consultas SQL dinámicas en su código de cliente, deberá actualizar el código de la aplicación si se produce un error en la consulta SQL. Esto significa que tendrá que volver a compilar e implementar el código de la aplicación.
Tráfico de red
Los procedimientos almacenados producen menos tráfico de red que el SQL dinámico porque ejecutar un procedimiento almacenado requiere que solo el nombre del procedimiento y los parámetros (si los hay) se envíen a través de la red.
La ejecución de SQL dinámico requiere que la consulta completa se envíe a través de la red, lo que aumenta el tráfico de la red, especialmente si la consulta es muy grande.
Ataques de inyección SQL
Los procedimientos almacenados no son vulnerables a los ataques de inyección SQL.
Las consultas de SQL dinámico son vulnerables a los ataques de inyección de SQL si no se usan consultas parametrizadas, y las consultas parametrizadas no se pueden usar con SQL dinámico si se pasa un nombre de tabla o columna como parámetro.
En este caso, la solución es que la función de nombre de código se puede usar para evitar ataques de inyección SQL.
Reutilización de planes de consultas en caché
Los procedimientos almacenados mejoran el rendimiento de la base de datos, ya que permiten reutilizar los planes de consulta en caché. En el caso de SQL dinámico, tendrá que usar consultas parametrizadas para aumentar la reutilización del plan de consultas en caché. En ausencia de planes de consulta parametrizados, el servidor SQL detecta automáticamente los parámetros y genera planes de consulta en caché, lo que mejora el rendimiento.
Es pertinente mencionar aquí que solo los sistemas OLTP se benefician de la reutilización del plan de consulta en caché. En el caso de los sistemas OLAP, la elección del optimizador cambia, el sistema OLAP se beneficia del plan único.
Mantenimiento
Los procedimientos almacenados con SQL estático son más fáciles de mantener. Por ejemplo, en el caso de SQL estático en un procedimiento almacenado, los errores de sintaxis pueden detectarse antes de ejecutarse. En el caso de SQL dinámico dentro de los procedimientos almacenados, los errores de sintaxis no se pueden detectar antes de la ejecución de la consulta.
Además, los procedimientos almacenados son más como funciones, se definen una vez y luego se pueden llamar en cualquier parte del script. Por lo tanto, si desea actualizar un procedimiento almacenado, solo debe actualizarlo en un lugar. Todas las partes de la aplicación que llamen al procedimiento almacenado tendrán acceso a la versión actualizada. Sin embargo, una desventaja es que esas partes de la aplicación también pueden verse afectadas cuando no desea el procedimiento almacenado actualizado. En el caso de SQL dinámico, es posible que deba escribir secuencias de comandos SQL en varios lugares, pero en tales casos, actualizar la secuencia de comandos en un lugar no afecta al otro. La decisión entre usar un procedimiento almacenado y SQL dinámico depende de la funcionalidad de la aplicación.
Seguridad
Si múltiples aplicaciones acceden a la base de datos, es más seguro usar procedimientos almacenados que SQL dinámico.
Los procedimientos almacenados brindan una capa adicional de seguridad, mientras que el contexto del usuario es la única forma de controlar los permisos en los scripts SQL dinámicos. Con todo, asegurar SQL dinámico es laborioso en comparación con los procedimientos almacenados.
Identificación de dependencias
En una base de datos relacional, las tablas tienen dependencias con otras tablas de la base de datos.
Considere un escenario en el que desea eliminar una tabla pero, antes de hacerlo, desea conocer todas las dependencias de la tabla. O en términos simples, desea encontrar las consultas que acceden a la tabla que desea eliminar. En estos casos, puede utilizar el procedimiento almacenado sp_depends.
Sin embargo, sp_depends solo puede detectar aquellas dependencias donde se usa SQL estático dentro de un procedimiento almacenado. En el caso de que el SQL dinámico dependa de una tabla, el procedimiento almacenado sp_depends no puede detectar esa dependencia. Veamos esto en acción con la ayuda de un ejemplo simple.
Preparación de datos ficticios
Vamos a crear algunos datos ficticios para ayudar a explicar el concepto de dependencias en SQL estático y dinámico.
CREATE DATABASE deptest; USE deptest CREATE TABLE student ( Id int identity primary key, Name VARCHAR(50) NOT NULL, Gender VARCHAR(50) NOT NULL, Age int ) INSERT INTO student VALUES ('James', 'Male', 20), ('Helene', 'Female', 20), ('Sofia', 'Female', 20), ('Ed', 'Male', 20), ('Ron', 'Female', 20)
Ahora tenemos una base de datos de prueba que contiene una tabla y algunos datos de prueba. Ahora vamos a crear dos procedimientos almacenados que accedan a la tabla de estudiantes.
El primer procedimiento almacenado usa SQL estático para recuperar todos los registros de la tabla de estudiantes:
USE deptest GO CREATE PROC spStatProc AS BEGIN SELECT * FROM student END
Ejecute el script anterior. Este script crea un procedimiento almacenado "spStatProc" dentro de la base de datos más profunda.
Vamos a crear otro procedimiento almacenado que contenga SQL dinámico que recupere todos los registros de la tabla de estudiantes.
USE deptest GO CREATE PROC spDynProc AS BEGIN DECLARE @query NVARCHAR(100) SET @query = 'SELECT * FROM student' EXECUTE sp_execute @query END
Este script crea un procedimiento almacenado "spDynProc" dentro de la base de datos más profunda. Este procedimiento almacenado utiliza una instrucción SQL dinámica para recuperar todos los registros de la tabla de estudiantes.
Ahora tenemos dos procedimientos almacenados que dependen de la tabla de estudiantes. Uno de ellos contiene SQL estático y el otro contiene SQL dinámico.
Sin embargo, si ejecuta el procedimiento almacenado sp_depends y lo pasa a la tabla de estudiantes como parámetro, verá que solo recuperará el procedimiento almacenado "spStatProc". Esto se debe a que contiene SQL estático. El procedimiento almacenado “spDynProc” será ignorado ya que contiene SQL dinámico.
Ejecute el siguiente script.
USE deptest GO EXECUTE sp_depends student
Obtendrá el siguiente resultado:
[identificación de la tabla=40 /]
Puede ver que sp_depends no pudo informar la dependencia "spDynProc" y solo informó "spStatProc".
Complejidad
Los procedimientos almacenados pueden volverse extremadamente complejos si usa una gran cantidad de filtros y hay varias cláusulas AND y OR entre los filtros. Por otro lado, usando SQL dinámico puedes generar dinámicamente cláusulas WHERE dependiendo del tipo de filtros. Esto hace que SQL dinámico sea la mejor opción si desea implementar una lógica extremadamente compleja.
Conclusión
En general, el procedimiento almacenado supera al SQL dinámico en casi todos los aspectos. Son más rápidos, seguros y fáciles de mantener, y requieren menos tráfico de red. Como regla general, los procedimientos almacenados deben usarse en escenarios en los que no tiene que modificar sus consultas y sus consultas no son muy complejas. Sin embargo, si cambia con frecuencia los nombres de las tablas, los nombres de las columnas o la cantidad de parámetros en su consulta, Dynamic SQL es la mejor opción debido a su estrategia de implementación más simple.
Enlaces útiles
- SQL dinámico versus procedimientos almacenados
- No temas SQL dinámico
- Creación de procedimientos almacenados de alto rendimiento
- Clases de Procedimientos Almacenados