Deaktivieren der Überprüfung des Schemas bei der Erstellung von Funktionen / gespeicherten Prozeduren

17

Ich versuche, den Prozess zu automatisieren, der Änderungen an der SQL Server 2008 R2-Datenbank ausführt. Der Prozess, den ich eingerichtet habe, löscht meine gespeicherten Prozeduren und Funktionen und erstellt sie neu. Außerdem werden Skripts ausgeführt, um die Tabellen / Spalten / Daten zu ändern. Leider erfordert eines der Skripte, dass eine der Funktionen zuerst eingerichtet wird. Ich kann jedoch nicht alle gespeicherten Änderungen an Prozessen / Funktionen zuerst ausführen, da dies darauf beruht, dass zuerst Spalten aus den Skripten für Tabellen / Spalten / Datenänderungen hinzugefügt werden.

Ich habe mich gefragt, ob es möglich ist, gespeicherte Prozeduren und Funktionen auszuführen, ohne dass SQL Server die in der Definition der Funktion / SP verwendeten Spalten überprüft. Ich habe versucht zu suchen, konnte aber keine Bedingung oder keinen Befehl finden, um dies zu ermöglichen.

Brian Mains
quelle
Es hört sich so an, als müssten Sie möglicherweise nur die Objekterstellung in Ihren Skripten neu anordnen.
Thomas Stringer
@shark Es ist so, dass ein Änderungsskript eine Abhängigkeit von einer Funktion erfordert, die zu diesem Zeitpunkt noch nicht vorhanden war. Ich wollte etwas Automatischeres.
Brian Mains

Antworten:

20

Sie können gespeicherte Prozeduren erstellen , die auf noch nicht vorhandene Objekte verweisen (z. B. Tabellen und Funktionen). Sie können keine gespeicherten Prozeduren erstellen, die auf Spalten verweisen, die noch nicht in bereits vorhandenen Objekten vorhanden sind. Dies ist das zweischneidige Schwert der verzögerten Namensauflösung - mit SQL Server können Sie in einigen Fällen, aber nicht in allen Fällen, den Vorteil von Zweifeln genießen. Sehen Sie sich Erlands Ideen an SET STRICT_CHECKS ON;, um sich ein Bild von den Orten zu machen, an denen dies funktioniert und an denen es bricht:

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

(Und wie er das genaue Gegenteil von dem haben möchte, wonach Sie suchen - Sie möchten zulassen, dass alles kompiliert wird, unabhängig von der Existenz, und er möchte, dass jede einzelne Spalte oder Tabelle überprüft wird.)

Es gibt keine Einstellung, nach der SET DEFERRED_NAME_RESOLUTION OFF;gefragt wurde:

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

Und es gibt keine Einstellung wie IGNORE ALL_RESOLUTION;.


Sie können dies auf verschiedene Arten umgehen, einschließlich:

(a) Verwenden Sie dynamisches SQL in den betroffenen gespeicherten Prozeduren.

(b) Erstellen Sie einen Stub CREATE PROCEDUREmit nichts darin, führen Sie dann den Rest Ihres Skripts aus, und führen Sie dann einen aus, ALTER PROCEDUREder den eigentlichen Text enthält (implementieren Sie die Prozedur im Wesentlichen in zwei Phasen).

(c) Machen Sie Ihr Bereitstellungstool in Bezug auf die Reihenfolge der Operationen intelligenter. Wenn Tabellenänderungen das Vorhandensein einer Funktion erfordern, schreiben Sie diese Änderungen zuletzt. Mit Schemavergleichstools wie SQL Compare von RedGate können Sie Skripts in der richtigen Abhängigkeitsreihenfolge generieren. Sie erwähnen nicht, welches Tool Sie verwenden, aber wenn dies nicht der Fall ist ...

(d) Martin Smith hat hier eine interessante Problemumgehung , aber ich habe nicht damit gespielt.

Aaron Bertrand
quelle
Wow, dieser Martin-Smith-Hack ist genial schlau. Ich würde mich jetzt schmutzig fühlen, aber in meinen frühen 20ern hätte.
John Zabroski
1

Sie können eine gespeicherte Prozedur erstellen, die zuerst das betreffende Objekt löscht oder umbenennt und dann Ihre ursprüngliche gespeicherte Prozedur als dynamisches SQL ausführt. Auf diese Weise müssen Sie die tatsächlich gespeicherte Prozedur nicht neu schreiben, um dynamisches SQL zu verwenden.

Im folgenden Code wird eine gespeicherte Prozedur ausgeführt, die auf noch nicht vorhandene Spalten verweist (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
quelle