2010-11-30 6 views
11

Microsoft SQL Server semble vérifier la validité du nom de colonne, mais pas la validité du nom de la table lors de la définition des procédures stockées. S'il détecte qu'un nom de table référencé existe actuellement, il valide les noms de colonne dans une instruction par rapport aux colonnes de cette table. Ainsi, par exemple, cela se déroulera sur OK:Pourquoi Microsoft SQL Server vérifie-t-il les colonnes mais pas les tables dans les procs stockés?

CREATE PROCEDURE [dbo].[MyProcedure] 
AS 
BEGIN 
    SELECT 
     Col1, Col2, Col3 
    FROM 
     NonExistentTable 
END 
GO 

... tout comme ceci:

CREATE PROCEDURE [dbo].[MyProcedure] 
AS 
BEGIN 
    SELECT 
     ExistentCol1, ExistentCol2, ExistentCol3 
    FROM 
     ExistentTable 
END 
GO 

... mais cela ne fonctionne pas, avec 'nom de colonne non valide':

CREATE PROCEDURE [dbo].[MyProcedure] 
AS 
BEGIN 
    SELECT 
     NonExistentCol1, NonExistentCol2, NonExistentCol3 
    FROM 
     ExistentTable 
END 
GO 

Pourquoi SQL Server vérifie-t-il l'existence des colonnes, mais pas des tables? Sûrement c'est inconsistant; il devrait faire les deux, ou aucun. Il est utile de pouvoir définir des SP qui peuvent se référer à des tables ET/OU des colonnes qui n'existent pas encore dans le schéma. Il est donc possible de désactiver la vérification de l'existence des colonnes SQL Server dans les tables existantes ?

Répondre

17

Ceci est appelé résolution de nom différée.

Il n'y a aucun moyen de l'éteindre. Vous pouvez utiliser le SQL dynamique ou (un hack méchant!) Ajouter une référence à une table inexistante afin que la compilation de cette déclaration soit différée.

CREATE PROCEDURE [dbo].[MyProcedure] 
AS 
BEGIN 

CREATE TABLE #Dummy (c int) 

    SELECT 
     NonExistantCol1, NonExistantCol2, NonExistantCol3 
    FROM 
     ExistantTable 
    WHERE NOT EXISTS(SELECT * FROM #Dummy)  


DROP TABLE #Dummy 

END 
GO 
+0

Qui est; la non-vérification des tables, ou la vérification des colonnes? – Jez

+0

La non vérification des tables. Si toutes les tables utilisées dans une instruction existent, elles ne sont pas différées. –

+0

Merci pour l'explication; Pourquoi avez-vous besoin de DROP TABLE #Dummy? Les tables temporaires ne sont-elles pas automatiquement supprimées une fois le proc stocké terminé? – Jez

-2

Cet article dans MSDN devrait répondre à votre question.

de l'article:

Lorsqu'une procédure stockée est exécutée pour la première fois, le processeur requête lit le texte de la procédure stockée dans la vue du catalogue sys.sql_modules et vérifie que les noms de les objets utilisés par la procédure sont présents. Ce processus est appelé résolution de nom différée car les objets de table référencés par la procédure stockée ne doivent pas nécessairement exister lors de la création de la procédure stockée, mais uniquement lorsqu'elle est exécutée.

+0

OK, cela répond au 'comment' mais pas au 'pourquoi' Comme dans, quelle est la justification de MS pour ce faire?Il serait plus utile de faire différer la résolution de noms sur les noms de colonnes (ou cette option était disponible). – Jez

+0

Bien que SQL Server prenne la validation autant que possible, non? Si la table existe, vérifiez ses colonnes. Sinon, si la table n'existe pas encore, il n'y a aucun moyen de vérifier ses colonnes. – bitxwise

+1

Non ... SQL Server peut dire, 'erreur. la table n'existe pas. Il n'est pas nécessaire d'autoriser la résolution de noms différée. D'un autre côté, il pourrait réaliser qu'une colonne n'existe pas encore mais différer la résolution dessus parce que vous pourriez continuer à changer le schéma plus tard. Le report de la résolution du nom de la table, mais pas de la résolution du nom de la colonne, semble simplement irrationnellement incohérent. – Jez