Wie erstelle ich eine bedingte gespeicherte Prozedur in SQL Server?
-
09-06-2019 - |
Frage
Als Teil meiner Integrationsstrategie führe ich einige SQL-Skripte aus, um die Datenbank zu aktualisieren.Alle diese Skripte prüfen zunächst, ob sie ausgeführt werden müssen, z. B.:
if @version <> @expects
begin
declare @error varchar(100);
set @error = 'Invalid version. Your version is ' + convert(varchar, @version) + '. This script expects version ' + convert(varchar, @expects) + '.';
raiserror(@error, 10, 1);
end
else
begin
...sql statements here...
end
Funktioniert super!Außer wenn ich eine gespeicherte Prozedur hinzufügen muss.Der Befehl „create proc“ muss der einzige Befehl in einem Stapel von SQL-Befehlen sein.Das Einfügen eines „create proc“ in meine IF-Anweisung verursacht diesen Fehler:
'CREATE/ALTER PROCEDURE' must be the first statement in a query batch.
Autsch!Wie füge ich den CREATE PROC-Befehl in mein Skript ein und lasse ihn nur dann ausführen, wenn es nötig ist?
Lösung
Hier ist, was ich kam mit:
Wickeln Sie es in einem exec (), etwa so:
if @version <> @expects
begin
...snip...
end
else
begin
exec('CREATE PROC MyProc AS SELECT ''Victory!''');
end
Funktioniert wie ein Zauber!
Andere Tipps
SET NOEXEC ON ist guter Weg, einen Teil des Codes zum Ausschalten
IF NOT EXISTS (SELECT * FROM sys.assemblies WHERE name = 'SQL_CLR_Functions')
SET NOEXEC ON
GO
CREATE FUNCTION dbo.CLR_CharList_Split(@list nvarchar(MAX), @delim nchar(1) = N',')
RETURNS TABLE (str nvarchar(4000)) AS EXTERNAL NAME SQL_CLR_Functions.[Granite.SQL.CLR.Functions].CLR_CharList_Split
GO
SET NOEXEC OFF
hier gefunden: https://codereview.stackexchange.com/ Fragen / 10490 / bedingte-create-muss-sein-das-nur-statement-in-the-Batch
P. S. Ein anderer Weg ist SET parseonly {ON | AUS }.
Aber achten Sie auf einfache Anführungszeichen in Ihrer gespeicherten Prozedur - sie müssen durch Hinzufügen eines zweiten „entkommen“ werden. Die erste Antwort hat dies getan, aber nur für den Fall, dass Sie es verpasst. Eine Falle für junge Spieler.
Ihre Datenbank Versionierung ist der Weg zu gehen, aber ... Warum bedingt gespeicherte Prozeduren erstellen. Für Views, Stored Procedures, Funktionen, fallen sie nur bedingt und neu erstellen sie jedes Mal. Wenn Sie bedingt erstellen, dann werden Sie nicht clean-up-Datenbanken, die ein Problem oder einen Hack, die von einem anderen Entwickler in 2 Jahren gestellt habe (du oder ich würde das nie tun), der war sicher, er würde daran denken, die einmal zu entfernen Notfall-Update.
Problem mit Drop und Erstellen ist Sie alle Sicherheits gewährt, die zuvor auf das Objekt angewandt worden war, fallen gelassen zu werden.
Ich muss zugeben, ich würde normalerweise mit @ Peter zustimmen - ich bedingt löschen und dann neu erstellen bedingungslos jedes Mal. Ich habe zu viele Male in der Vergangenheit gefangen, wenn sie versuchen, um die Schema-Unterschiede zwischen den Datenbanken zweiten zu erraten, mit oder ohne irgendeine Form der Versionskontrolle.
Having said that, Ihr eigener Vorschlag @ Josh ist ziemlich cool. Sicher interessant. : -)
Dies ist ein alter Thread, aber Jobo ist falsch: Vorgehensweise Erstellen Sie die erste Anweisung in einem Batch sein muss. Daher können Sie nicht Exists
verwenden Existenz zu testen und dann entweder Create
oder Alter
verwenden. Schade.
Meine Lösung ist, wenn die Prozedur besteht zu überprüfen, wenn ja, dann fallen lassen, und erstellen Sie dann das proc (gleiche Antwort wie @robsoft aber mit einem Beispiel ...)
IF EXISTS(SELECT * FROM sysobjects WHERE Name = 'PROC_NAME' AND xtype='P')
BEGIN
DROP PROCEDURE PROC_NAME
END
GO
CREATE PROCEDURE PROC_NAME
@value int
AS
BEGIN
UPDATE SomeTable
SET SomeColumn = 1
WHERE Value = @value
END
GO
Verwenden Sie die 'Exists' Befehl in T-SQL, um zu sehen, ob die gespeicherte Prozedur vorhanden ist. Ist dies der Fall, verwenden Sie ‚Alter‘, sonst Gebrauch ‚Erstellen‘
IF NOT EXISTS(SELECT * FROM sys.procedures WHERE name = 'pr_MyStoredProc')
BEGIN
CREATE PROCEDURE pr_MyStoredProc AS .....
SET NOCOUNT ON
END
ALTER PROC pr_MyStoredProc
AS
SELECT * FROM tb_MyTable