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?

War es hilfreich?

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
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top