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

17

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 toutes les modifications de proc / fonction stockées en premier car cela repose sur l'ajout de colonnes à partir des scripts de modification des 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.

Brian Mains
la source
Il semble que vous ayez juste besoin de réorganiser la création d'objet dans vos scripts.
Thomas Stringer
@shark C'est qu'un script de changement nécessite une dépendance à une fonction, ce qui n'était pas le cas à l'époque ... pour ce faire, il faudrait une intervention manuelle; Je voulais quelque chose de plus automatique.
Brian Mains

Réponses:

20

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;avoir une idée des endroits où cela fonctionne et des endroits 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 permettre à tout de compiler 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;cela a été demandé:

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

Et il n'y a pas de réglage 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) construisez un stub pour CREATE PROCEDUREsans rien dedans, puis exécutez le reste de votre script, puis exécutez un ALTER PROCEDUREqui a le corps réel (essentiellement, déployez la procédure en deux phases).

(c) rendre votre outil de déploiement plus intelligent quant à l'ordre des opérations. Si les modifications de table nécessitent la présence d'une fonction, scriptez ces modifications 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.

Aaron Bertrand
la source
Wow, ce hack de Martin Smith est brillamment intelligent. Je me sentirais sale en l'utilisant maintenant, mais au début de la vingtaine.
John Zabroski
1

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 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');
Lou Fancy
la source