Comment puis-je détecter des procédures stockées rompues après un changement de schéma?

11

J'ai modifié une table centrale dans ma base de données et sp_depends renvoie littéralement des centaines de résultats, et je crains que certaines de ces procédures stockées ne se compilent plus après ma modification.

Il est facile de vérifier une seule procédure stockée (je viens de réexécuter le script alter et de voir si l'opération a réussi), mais cela sur plus de 100 procédures est un peu lourd.

Je sais que je peux utiliser un script comme celui-ci pour recompiler tous les objets de ma base de données, mais l'opération réelle aura lieu la prochaine fois que la procédure stockée sera exécutée, pas immédiatement, donc cela ne semble pas approprié dans mon cas.

Je pensais également que je pouvais supprimer toutes les procédures stockées et resynchroniser ma base de données avec mon système de contrôle de source, mais cette option, bien que viable, n'est pas très élégante. Existe-t-il une meilleure façon de le faire?

J'utilise SQLServer 2008 R2 et mes scripts de base de données sont stockés dans un projet de base de données VS 2008.


Pour clarifier, je ne préconise pas que l'on devrait s'appuyer uniquement sur cette approche pour tester le code. Tout comme en c #, vous détectez instantanément une erreur de syntaxe dans d'autres fichiers dépendants au fur et à mesure que vous codez (puis utilisez d'autres stratégies pour tester, comme les tests unitaires, qui sont généralement de plusieurs ordres de grandeur plus lents), je pense qu'il serait logique de détecter les dépendances SQL des erreurs en quelques secondes plutôt que d'avoir à exécuter un test fonctionnel complet qui peut généralement prendre quelques heures.

Brann
la source

Réponses:

7

Et si vous exécutiez vos tests unitaires, fonctionnels, d'intégration et de performance? Si vous n'avez aucun test, il est temps de commencer à considérer votre schéma de base de données comme du code et à le traiter comme tel, y compris le contrôle de version et les tests. Alex Kuznetsov a un livre entier consacré à ce sujet: Programmation de base de données défensive avec SQL Server .

Remus Rusanu
la source
Les tests ne couvrent pas toujours 100% du code et, lorsqu'ils le font, leur exécution prend généralement quelques heures. En c #, je peux détecter si mon code se compile toujours en quelques secondes (indépendamment de son exactitude). Cela ne signifie pas que je devrais pousser du code (quel que soit le code c # ou PLSQL) en production sans le tester correctement, mais il ne semble pas déraisonnable d'avoir un moyen de détecter rapidement les dépendances brisées, n'est-ce pas?
Brann
2
Malheureusement, l'état actuel de SQL Server vis-à-vis de la détection des dépendances dans la procédure stockée est `` profondément rompu '', voir Comprendre les dépendances SQL ou Garder sysdepends à jour dans SQL Server 2008 . Il existe même des outils tiers essayant de résoudre le problème
Remus Rusanu
2
Cela fait des tests unitaires / fonctionnels à peu près le seul moyen fiable de détecter les changements de rupture.
Remus Rusanu
1
Pour une vérification rapide, les projets de base de données Visual Studio font un travail assez décent pour valider toute modification.
Remus Rusanu
4

C'est un travail autour, mais vous pouvez générer les scripts CREATE PROCEDURE pour la base de données (base de données clic droit -> tâches -> générer des scripts), trouver et remplacer CREATE PROCEDURE par ALTER PROCEDURE puis analyser.

J'espère que vous obtenez une meilleure réponse ici - ça m'intéresse aussi! :)

JHFB
la source
Je ne marque pas votre réponse comme acceptée car j'espère toujours une solution plus propre (j'espère une solution scriptable), mais vous obtenez certainement mon +1! Merci.
Brann
3
Cette approche ne vous permettra pas de savoir si vous faites référence à une table inexistante .
Nick Chammas
Cette approche ne fonctionnera pas non plus si le script généré est supérieur à environ 30k lignes. Je déteste savoir ça ..
Eonasdan
3

Vous pouvez utiliser Sql Server Data Tools (SSDT). Microsoft Visual Studio vous permet de créer un projet Sql Server. On importe ensuite la base de données dans le projet, puis créez le projet. S'il y a des procédures stockées ou des objets cassés, vous obtiendrez une erreur de compilation.

VenVig
la source
J'ajouterai que vous pouvez facilement générer un nouveau script de création de base de données à partir du projet SSDT et l'exécuter dans un environnement de test, ce qui sera une vérification assez approfondie qu'il n'y a pas de procs / triggers / etc cassés en raison de changements de schéma.
AaronLS
3

Vous voudrez peut-être regarder cette question SO Je cherche un moyen fiable de vérifier les procédures stockées T-SQL. Quelqu'un en a un? qui demande essentiellement la même chose, avec plusieurs réponses.

Pour s'appuyer sur le script publié par Alaa Awad ... cela devrait montrer le schéma et la base de données des objets référencés et référençant. Si vous utilisez de nombreuses tables temporaires via des alias (qui apparaissent parfois lors de l'utilisation sys.sql_expression_dependencies), des paramètres UDTT ou d'autres fonctionnalités dynamiques, vous devrez peut-être utiliser les fonctions sys.dm_sql_referenced_entitiesou à la sys.dm_sql_referencing_entitiesplace / également.

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]
Arkaine55
la source
1
Devrait les ajouter à la clause where: / * Pas un UserType existant / AND sed.referenced_entity_name NOT IN (SELECT [name] FROM sys.types) / Pas un alias * / AND sed.referenced_schema_name IS NOT NULL
JasonBluefire
1

utiliser les sys.sql_expression_dependencies ajoutées dans 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
Alaa Awad
la source
Cela peut être utile, mais ce n'est pas aussi simple que le schéma doit également être pris en compte. Je reçois également des problèmes où sys.sql_expession_dependencies affiche l'alias utilisé plutôt que la table dépendante réelle, ce qui échoue évidemment au test object_id (). Enfin, il fait apparaître des tables définies par l'utilisateur passées en tant que paramètres aux procédures stockées - ce qui n'est pas vraiment utile.
Tabloo Quijico