2011-04-08 18 views
5

Tenemos un viejo proyecto de 10-12 años. Estaba usando SQL2000 que ahora hemos movido a SQL2008.¿El SQL formado dinámicamente en los procedimientos almacenados niega el propósito mismo de los procedimientos almacenados?

Durante esta tarea encontré que los procedimientos almacenados aceptaban parámetros y luego construían la consulta como una cadena y luego usaban EXEC para ejecutar el comando.

CREATE PROCEDURE MyProc 
    (@TableName varchar(255), 
    @FirstName varchar(50), 
    @LastName varchar(50)) 
AS 

    -- Create a variable @SQLStatement 
    DECLARE @SQLStatement varchar(255) 

    -- Enter the dynamic SQL statement into the 
    -- variable @SQLStatement 
    SELECT @SQLStatement = "SELECT * FROM " + 
        @TableName + "WHERE FirstName = '" 
        + @FirstName + "' AND LastName = '" 
        + @LastName + "'" 

    -- Execute the SQL statement 
    EXEC(@SQLStatement) 

Este es un mal enfoque. ¿Esto elimina los beneficios del procedimiento almacenado (beneficio de consulta precompilado)?

+0

Si el único propósito del procedimiento es hacer una selección de esa manera, entonces sí, parece una mala idea, pero solo porque es un diseño deficiente, no por razones de rendimiento. – JNK

+0

+1 la pregunta, entiendo que esto es solo un ejemplo, la pregunta es, en general, ¿esto mata los beneficios del procedimiento almacenado? digamos en un sproc más complejo. –

+0

sí, el SP es solo un ejemplo simple, pero el que me preocupa es realmente grande y feo ... tienen patrones como los siguientes, por ejemplo, formando una declaración de selección intermedia y rellenando la tabla temporal entre la ejecución de la selección final en ella para paginación ... y cosas –

Respuesta

7

No, y yo diría que el beneficio principal de los procedimientos almacenados ya no es el hecho de que esté "precompilado" (desde 2005 o antes, quizás nunca, excepto para llamadas de muy alto volumen).

Hay un caché de planes que también está disponible para declaraciones ad hoc.

Este ejemplo particular ha vuelto a introducir una vulnerabilidad de la inyección que sería automática con:

CREATE PROCEDURE MyProc 
    (@FirstName varchar(50), 
    @LastName varchar(50)) 
AS 
BEGIN 
    SELECT * FROM TABLENAME 
    WHERE FirstName = @FirstName 
     AND LastName = @LastName 
END 

Todo por el bien de ser parametrizado en nombre de la tabla.

Beneficios de procedimientos almacenados incluyen:

  • gestión de la seguridad (ser capaz de controlar los derechos EXEC independientemente de SELECT/INSERT/UPDATE)

  • acceso Coordinación (garantizar todas las operaciones se realizan en cierta maneras)

  • Organización (siendo capaz de organizar la interfaz de la base de datos de una manera coherente)

  • Prevención de inyección (los procedimientos almacenados siempre están parametrizados, esto asegura que los llamantes no pueden crear casos de base de datos que son vulnerables a la inyección; tenga en cuenta que los SP deben ser escritos correctamente, pero los programadores no podrán introducir inyecciones si sólo tienen acceso a los PE y no tablas)

  • inventario del sistema (poder definir el perfil y optimizar ciertos procedimientos por su nombre, ser capaz de tener una capa de interfaz completa y bien documentada compuestos de procedimientos almacenados)

SQL dinámico en un SP tiene su lugar, y puede negar algunas cosas, como la seguridad (inicia una nueva cadena, por lo que los permisos de SELECCIONAR deberán otorgarse aquí) y la inyección. El almacenamiento en caché del plan de ejecución no es uno que yo pondría en primer lugar en la lista.

0

depende de la complejidad del plan de ejecución. Para este caso particular, no veo ningún problema con el procedimiento almacenado, ya que el plan de ejecución será bastante simple.

1

En lugar de EXEC (@SQL) intente sp_execute (@SQL).

sp_execute (@SQL) promueve la reutilización del plan de consulta. Al usar sp_executesql, un usuario o una aplicación identifica explícitamente los parámetros. Lea acerca de los problemas de caché del plan here en este artículo de TechNet, consulte el n. ° 3.

+0

También recomendaría este artículo que explica las trampas de sp_executesql http://www.sqlskills.com/BLOGS/KIMBERLY/post/EXEC-and-sp_executesql-how-are-they-different.aspx –

1

Depende de lo que considere el 'propósito' de los procedimientos almacenados. Yo argumentaría que existen procedimientos almacenados para exponer una API asegurable a la base de datos y aislar la (s) aplicación (es) de la implementación de la base de datos, al mantener SQL fuera de la base del código.

Al hacerlo, hace que la base de datos sea un componente separado que puede modificarse y versionarse independientemente del código de la aplicación que hace referencia a él (siempre que la firma de la API no cambie).

Si todo el acceso a su base de datos es a través de procedimientos almacenados, siempre y cuando los argumentos del procedimiento almacenado y los conjuntos de resultados no cambien, los DBAs son libres de ajustar consultas y remodelar el db al contenido de sus corazones, siempre y cuando No rompa las suposiciones que el código hace sobre el modelo de datos: uno puede [teóricamente] cambiar completamente el esquema subyacente sin requerir cambios de código.

Ese es el verdadero beneficio de los procedimientos almacenados.

Cuestiones relacionadas