¿Cómo puedo detectar procedimientos almacenados rotos después de un cambio de esquema?


11

Modifiqué una tabla central en mi base de datos, y sp_depends literalmente devuelve cientos de resultados, y me preocupa que algunos de esos procedimientos almacenados ya no puedan compilarse después de mi cambio.

Verificar un solo procedimiento almacenado es fácil (solo vuelvo a ejecutar el script alter y veo si la operación es exitosa), pero hacerlo en más de 100 procedimientos es un poco engorroso.

Sé que puedo usar un script como este para recompilar todos los objetos de mi base de datos, pero la operación real tendrá lugar la próxima vez que se ejecute el procedimiento almacenado, no de inmediato, por lo que no parece apropiado en mi caso.

También estaba pensando que podría eliminar todos los procedimientos almacenados por completo y resincronizar mi base de datos con mi sistema de control de código fuente, pero esa opción, aunque viable, no es muy elegante. ¿Hay una mejor manera de hacer esto?

Estoy usando SQLServer 2008 R2 y mis scripts de base de datos se almacenan en un proyecto de base de datos VS 2008.


Para aclarar, no estoy recomendando que uno deba confiar únicamente en este enfoque para probar el código. Al igual que en C #, detecta instantáneamente un error de sintaxis en otros archivos dependientes a medida que codifica (y luego usa otras estrategias para probar, como pruebas unitarias, que generalmente son varios órdenes de magnitud más lentas), creo que tendría sentido detectar dependencias SQL errores en segundos en lugar de tener que ejecutar una prueba funcional completa que generalmente puede tardar algunas horas en completarse.

Respuestas:


7

¿Qué tal si ejecuta su unidad, pruebas funcionales, de integración y de rendimiento? Si no tiene ninguna prueba, entonces es un momento serio para comenzar a considerar su esquema de base de datos como código y tratarlo como tal, incluido el control de versión y las pruebas. Alex Kuznetsov tiene un libro completo dedicado a este tema: Programación defensiva de bases de datos con SQL Server .


Las pruebas no siempre cubren el 100% del código, y cuando lo hacen, generalmente demoran unas horas en ejecutarse. En c #, puedo detectar si mi código aún se compila en segundos (independientemente de si es correcto). Esto no significa que deba insertar código (independientemente de que el código sea c # o PLSQL) en producción sin probarlo adecuadamente, pero no parece irrazonable tener una forma de detectar rápidamente dependencias rotas, ¿verdad?
Brann

2
Desafortunadamente, el estado del arte de SQL Server en este momento con respecto a la detección de dependencias en el procedimiento almacenado está 'profundamente roto', vea Comprender las dependencias de SQL o Mantener sysdepends actualizado en SQL Server 2008 . Incluso hay herramientas de terceros que intentan abordar el problema
Remus Rusanu

2
Esto hace que las pruebas unitarias / funcionales sean prácticamente la única forma confiable de detectar cambios importantes.
Remus Rusanu

1
Para una verificación rápida, Visual Studio Database Projects hace un trabajo bastante decente al validar cualquier cambio.
Remus Rusanu

4

Es una solución, pero podría generar los scripts CREATE PROCEDURE para la base de datos (haga clic con el botón derecho en la base de datos -> tareas -> generar scripts), busque y reemplace CREATE PROCEDURE con ALTER PROCEDURE y luego analice.

Espero que obtengas una mejor respuesta aquí. ¡También estoy interesado! :)


No estoy marcando su respuesta como aceptada porque todavía espero una solución más limpia (espero que sea una secuencia de comandos), ¡pero definitivamente obtienes mi +1! Gracias.
Brann

3
Este enfoque no le permitirá saber si está haciendo referencia a una tabla inexistente .
Nick Chammas

Este enfoque tampoco funcionará si el script generado es mayor que alrededor de 30k líneas. Odio saber esto ...
Eonasdan

3

Puede usar las Herramientas de datos del servidor SQL (SSDT). Microsoft Visual Studio le permite crear un proyecto de servidor SQL. Luego se importa la base de datos al proyecto y luego se construye el proyecto. Si hay procedimientos u objetos almacenados dañados, obtendrá un error de compilación.


Agregaré que puede generar fácilmente un nuevo script de creación de base de datos desde el proyecto SSDT y ejecutarlo en un entorno de prueba, lo que será una verificación bastante exhaustiva de que no hay procesos / disparadores / etc. rotos debido a cambios en el esquema.
AaronLS

3

Es posible que desee ver esta pregunta SO . Estoy buscando una forma confiable de verificar los procedimientos almacenados de T-SQL. ¿Alguien tiene uno? que pregunta esencialmente lo mismo, con varias respuestas.

Para construir sobre el script que Alaa Awad publicó ... esto debería mostrar el esquema y la base de datos de los objetos referenciados y de referencia. Si está usando muchas tablas temporales a través de alias (que a veces aparecen cuando se usa sys.sql_expression_dependencies), parámetros UDTT u otras características dinámicas, es posible que necesite usar las funciones sys.dm_sql_referenced_entitieso en su sys.dm_sql_referencing_entitieslugar / también.

SELECT
    DB_NAME() + '.' + OBJECT_SCHEMA_NAME(sed.referencing_id) + '.' + OBJECT_NAME(sed.referencing_id) AS [referencingObject],
    isnull(sed.referenced_server_name + '.', '') + isnull(sed.referenced_database_name + '.', DB_NAME() + '.') + isnull(sed.referenced_schema_name + '.', OBJECT_SCHEMA_NAME(sed.referencing_id) + '.') + sed.referenced_entity_name AS [missingReference]
FROM 
    sys.sql_expression_dependencies sed
WHERE 
    sed.is_ambiguous = 0
    AND OBJECT_ID(isnull(sed.referenced_database_name + '.', DB_NAME() + '.') + isnull(sed.referenced_schema_name + '.', OBJECT_SCHEMA_NAME(sed.referencing_id) + '.') + sed.referenced_entity_name) IS NULL
ORDER BY
    [referencingObject], [missingReference]

1
Debería agregarlos a la cláusula where: / * No es un tipo de usuario existente / AND sed.referenced_entity_name NOT IN (SELECT [name] FROM sys.types) / Not a alias * / AND sed.referenced_schema_name NO ES NULO
JasonBluefire

1

use las dependencias sys.sql_expression_dependencies agregadas en sql server 2008

CREATE PROCEDURE [dbo].[spMaintenance_Find_Broken_Dependencies]

AS
SELECT
    OBJECT_NAME(referencing_id) AS [referencingObject],
    referenced_entity_name AS [missingReference]
FROM 
    sys.sql_expression_dependencies
WHERE 
    is_ambiguous = 0
    AND OBJECT_ID(referenced_entity_name) IS NULL
ORDER BY 
    OBJECT_NAME(referencing_id), referenced_entity_name

GO

Esto puede ser útil, sin embargo, no es tan simple como el esquema también necesita tener en cuenta. También recibo problemas en los que sys.sql_expession_dependencies muestra el alias utilizado en lugar de la tabla dependiente real, lo que obviamente falla en la prueba object_id (). Finalmente, muestra tablas definidas por el usuario que se pasan como parámetros a los procedimientos almacenados, lo que no es realmente útil.
Tabloo Quijico
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.