2010-11-30 2 views
11

Microsoft SQL Server scheint die Gültigkeit des Spaltennamens, aber nicht die Gültigkeit des Tabellennamens zu überprüfen, wenn gespeicherte Prozeduren definiert werden. Wenn festgestellt wird, dass derzeit ein referenzierter Tabellenname vorhanden ist, werden die Spaltennamen in einer Anweisung anhand der Spalten in dieser Tabelle überprüft. So zum Beispiel wird dies laufen OK:Warum prüft Microsoft SQL Server Spalten, aber keine Tabellen in gespeicherten Procs?

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

... ebenso wie folgt aus:

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

... aber dies nicht gelingt, mit 'Ungültiger Spaltenname':

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

Warum prüft SQL Server Spalten, aber keine Tabellen auf Existenz? Sicher ist es inkonsequent; es sollte beides oder keines tun. Es ist für uns nützlich, SPs zu definieren, die sich auf Tabellen UND/ODER-Spalten beziehen, die noch nicht im Schema vorhanden sind, also gibt es eine Möglichkeit, die Überprüfung der Spaltenexistenz in Tabellen, die derzeit existieren, zu deaktivieren ?

Antwort

17

Dies wird als verzögerte Namensauflösung bezeichnet.

Es gibt keine Möglichkeit, es auszuschalten. Sie können dynamisches SQL verwenden oder (ein böser Hack!) Einen Verweis auf eine nicht existierende Tabelle hinzufügen, so dass die Kompilierung dieser Anweisung zurückgestellt wird.

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

Welches ist; die Nichtüberprüfung von Tabellen oder die Überprüfung von Spalten? – Jez

+0

Die Nichtüberprüfung von Tabellen. Wenn alle in einer Anweisung verwendeten Tabellen existieren, werden sie nicht zurückgestellt. –

+0

Danke für die Erklärung; Warum musstest du DROP TABLE #Dummy? Werden temporäre Tabellen nicht automatisch gelöscht, nachdem der gespeicherte Prozess beendet wurde? – Jez

-2

Dieser Artikel in MSDN sollte Ihre Frage beantworten.

Aus dem Artikel:

Wenn eine gespeicherte Prozedur zum ersten Mal ausgeführt wird, liest die Abfrage Prozessor den Text der gespeicherten Prozedur aus der sys.sql_modules Katalogsicht und prüft, ob die Namen des Die von der Prozedur verwendeten Objekte sind vorhanden. Dieser Prozess wird als deferated Namensauflösung bezeichnet, da Tabellenobjekte, auf die durch die gespeicherte -Prozedur verwiesen wird, nicht existieren müssen, wenn die gespeicherte Prozedur erstellt wird, sondern nur, wenn sie ausgeführt wird.

+0

OK, das beantwortet das "Wie", aber nicht das "Warum". Wie lautet die Begründung der MS dafür?Es wäre nützlicher, wenn sie auch die Auflösung des aufgeschobenen Namens für die Spaltennamen hätten (oder diese Option verfügbar wäre). – Jez

+0

Well SQL Server nimmt Validierung so weit wie möglich, oder? Wenn die Tabelle existiert, überprüfen Sie ihre Spalten. Andernfalls, wenn die Tabelle noch nicht existiert, gibt es keine Möglichkeit, ihre Spalten zu überprüfen. – bitxwise

+1

Nein ... SQL Server könnte "Fehler" sagen. Tabelle existiert nicht. Es muss keine verzögerte Namensauflösung zulassen. Auf der anderen Seite könnte es erkennen, dass eine Spalte noch nicht existiert, aber die Auflösung verschieben, weil Sie später das Schema ändern könnten. Die Verschiebung der Tabellennamenauflösung, aber nicht die Auflösung des Spaltennamens, scheint nur irritierend inkonsistent zu sein. – Jez

Verwandte Themen