2012-12-13 13 views
19

Oracle Oracle "erstellen oder ersetzen" Anweisungen. Sql-Server scheint nicht - wenn Sie aus Enterprise Manager scripten, schlägt stattdessen stattdessen "drop and create" vor. Das Löschen und Erstellen ist in jeder Situation, in der Sie Grants für die gespeicherte Prozedur ausgeführt haben, unerwünscht, weil dadurch die von Ihrem Datenbankadministrationsteam gewährten Grants verloren gehen. Sie müssen wirklich "create or replace" erstellen, um bei der Trennung von Conerns zwischen Entwicklern und Administratoren zu helfen.erstellen Sie gespeicherte Prozedur, wenn nicht in SQL-Server

Was ich habe vor kurzem getan, ist dies:

use [myDatabase] 
go 

create procedure myProcedure as 
begin 
    print 'placeholder' 
end 
go 

alter procedure myProcedure as 
begin 
    -- real sproc code here 
end 
go 

Das tut, was ich will. Wenn die Prozedur nicht existiert, erstellen Sie sie und ändern Sie dann den richtigen Code. Wenn die Prozedur vorhanden ist, schlägt die Erstellung fehl, und die Änderer aktualisiert den Code mit dem neuen Code.

Es erstellt ein anderes Problem für die Administratoren, da das Erstellen einen irreführenden Fehler verursacht, wenn die gespeicherte Prozedur bereits vorhanden ist. Irreführend natürlich, dass Sie keinen roten Fehlertext sehen sollten, wenn das gewünschte Ergebnis eingetreten ist.

Hat jemand eine Möglichkeit, den roten Text zu unterdrücken? Alles, was ich versucht habe, führt zu einem "CREATE/ALTER PROCEDURE muss die erste Anweisung in einem Abfrage Batch" Fehler auf die eine oder andere Weise sein.

+0

Mögliches Duplikat [? Was tun Sie in SQL Server zu erstellen oder ändern] (http://stackoverflow.com/questions/1434160/what-do-you-do-in-sql -server-to-create-or-alter) – ruffin

+0

Ich werde darauf hinweisen, dass wenn Sie die Berechtigungen als Teil Ihres Procs Skript dann gibt es kein Problem in Drop und Create.Wenn Sie spezielle Berechtigung für einen Proc haben, dann ist es sollte Teil des Skripts sein, das im Quellcode-Repository gespeichert ist. Dann, wenn Sie gehen, um eine Änderung vorzunehmen, gibt es dort bereits Erlaubnis. – HLGEM

Antwort

46

Dies funktioniert und halten Sie die Berechtigungen intakt:

use [myDatabase] 
go 
if object_id('dbo.myProcedure', 'p') is null 
    exec ('create procedure myProcedure as select 1') 
go 
alter procedure myProcedure as 
SET NOCOUNT ON 
    -- real sproc code here. you don't really need BEGIN-END 
go 
+0

Hah. Ich hatte diesen Trick vergessen. – RBarryYoung

+0

Ich mag meinen Anfang. – quillbreaker

+0

Dies funktioniert auch mit benutzerdefinierten Funktionen, wo ich die Notwendigkeit für "ändern" gefunden habe, weil die Funktion von mehreren Dingen verwendet wurde. Für das OP wäre dies die bevorzugte Option, IMHO. – granadaCoder

9

So:

IF NOT EXISTS (SELECT * FROM sys.objects 
       WHERE object_id = OBJECT_ID(N'[dbo].[myProcedure]') 
        AND type in (N'P', N'PC')) 
BEGIN 
    EXEC(' 
     create procedure myProcedure as 
     begin 
      print ''placeholder'' 
     end 
     ') 
END 

EXEC(' 
    alter procedure myProcedure as 
    begin 
     -- real sproc code here 
    end 
    ') 

NOTES:

  1. erinnern Sie Ihre Angebote in den dynamischen SQL-Strings zu verdoppeln.
  2. Ich habe es für die Lesbarkeit eingerückt, aber das wird auch die zusätzlichen Einzug Leerzeichen zu Ihren tatsächlichen Prozeduren Auflistungen hinzufügen. Wenn Sie das nicht möchten, reduzieren Sie einfach die Einrückungsstufe für den dynamischen SQL-Text.
+0

FYI, ich versuche immer die BEGIN..ENDs hinzuzufügen, wenn Sie online posten. Nur weil ich gesehen habe, wie oft ein Anfänger sich selbst in den Fuß geschossen hat, als er versucht hat, eine Zeile zu einer anderen SQL hinzuzufügen, aber vergiss, den BEGIN hinzuzufügen.END. – RBarryYoung

+0

Extraneous, wirklich. Das "GO" in einer neuen Zeile deckt es vollständig ab. Was soll man sagen, jemand wird 'Begin ... End' nicht tun und weitere Statements nach' END', aber vor 'GO' platzieren? Aber es ist nur eine Meinung und jeder hat einen Anspruch darauf! – RichardTheKiwi

+0

@RichardTheKiwi: Das ist ein ungewöhnlicher Fehler. (Nun, Missverständnis GO ist ein häufiger Fehler, aber es manifestiert sich normalerweise anders, als Variablen außerhalb des Geltungsbereichs) Normalerweise ist das Problem, das ich ohne BEGIN..END sehe, dass sie vergessen werden, dass sie für mehrere Anweisungen in einer Verzweigung notwendig sind /Block. Wenn der Anfang ..ENDE ist da, es scheint sie visuell zu "erinnern", also werden sie die neue Zeile nicht außerhalb des Blocks platzieren. (zumindest habe ich diesen Fehler nie gesehen) – RBarryYoung

4

Schließlich ist der Tag hier ist, wo SQL Server eine gleichwertige ersetzen zu erstellen oder umgesetzt hat. Ihr Äquivalent ist "Erstellen oder Ändern". Dies ist ab SQL Server 2016 SP1 verfügbar. Beispiel Nutzung:

use [myDatabase] 
go 

Create or Alter procedure myProcedure as 
begin 
    -- procedure code here 
end 
go 
Verwandte Themen