web-dev-qa-db-fra.com

Désactivation de la vérification du schéma lors de la création de fonction / procédure stockée

J'essaie d'automatiser le processus qui exécute les modifications de la base de données SQL Server 2008 R2. Le processus que j'ai mis en place supprime et recrée mes procédures et fonctions stockées, ainsi que l'exécution de scripts pour modifier les tables/colonnes/données. Malheureusement, l'un des scripts nécessite la mise en place d'une des fonctions en premier. Mais je ne peux pas exécuter tous les changements de proc/fonction stockés en premier car cela repose sur l'ajout de colonnes à partir des scripts de changement de tables/colonnes/données.

Je me demandais s'il était possible d'exécuter des procédures et des fonctions stockées sans que SQL Server ne valide les colonnes utilisées dans la définition de la fonction/SP? J'ai essayé de chercher, mais je n'ai pas trouvé de condition ou de commande pour l'activer.

18
Brian Mains

Vous pouvez créer des procédures stockées qui référencent des objets qui n'existent pas encore (par exemple des tables et des fonctions). Vous ne pouvez pas créer de procédures stockées qui référencent des colonnes qui n'existent pas encore dans des objets qui existent déjà. Il s'agit de l'épée à double tranchant de la résolution de noms différée - SQL Server vous offre le bénéfice du doute dans certains cas, mais pas dans tous. Voir les idées d'Erland pour SET STRICT_CHECKS ON; pour avoir une idée des lieux où cela fonctionne et des lieux où il se casse:

http://www.sommarskog.se/strict_checks.html

(Et comment il aimerait l'opposé polaire de ce que vous recherchez - vous voulez autoriser tout ce qui se compile indépendamment de l'existence, et il veut que chaque colonne ou table soit vérifiée.)

Il n'y a pas de paramètre comme SET DEFERRED_NAME_RESOLUTION OFF; bien qu'il ait été demandé:

http://connect.Microsoft.com/sql/127152

Et il n'y a pas de paramètre comme IGNORE ALL_RESOLUTION;.


Vous pouvez contourner ce problème de plusieurs manières, notamment:

(a) utiliser du SQL dynamique dans les procédures stockées affectées.

(b) créer un stub pour CREATE PROCEDURE sans rien, puis exécutez le reste de votre script, puis exécutez un ALTER PROCEDURE qui a le corps réel (essentiellement, déployer la procédure en deux phases).

(c) rendre votre outil de déploiement plus intelligent quant à l'ordre des opérations. Si les changements de table nécessitent la présence d'une fonction, scriptez ces changements en dernier. Les outils de comparaison de schémas comme la comparaison SQL de RedGate sont assez bons pour générer des scripts pour vous dans l'ordre de dépendance approprié. Vous ne mentionnez pas quel outil vous utilisez, mais si ce n'est pas le cas ...

(d) Martin Smith a une solution intéressante ici , mais je n'ai pas joué avec.

21
Aaron Bertrand

Vous pouvez créer une procédure stockée qui supprime ou renomme d'abord l'objet en question, puis exécute votre procédure stockée d'origine en tant que SQL dynamique. De cette façon, vous n'avez pas à réécrire la procédure stockée réelle pour utiliser SQL dynamique.

Le code ci-dessous exécute une procédure stockée qui fait référence à des colonnes qui n'existent pas encore (Expense_Super_Compare)

IF OBJECT_ID('Expense_Super_Compare_Results', 'U') IS NOT NULL
BEGIN
     EXEC('DROP TABLE Expense_Super_Compare_Results');
END

exec('exec dbo.Expense_Super_Compare');
1
Lou Fancy