2012-12-13 142 views
19

Oracle會「創建或替換」語句。 Sql服務器似乎沒有 - 如果你正在從企業管理器腳本化,它反而建議「放棄並創建」。在存儲過程中完成授權的任何情況下,刪除和創建都是不可取的,因爲它會拋出數據庫管理團隊完成的任何授權。您確實需要「創建或替換」來幫助開發人員和管理員之間的分離。如果在sql server中不存在,則創建存儲過程

我最近一直在做這樣的:

use [myDatabase] 
go 

create procedure myProcedure as 
begin 
    print 'placeholder' 
end 
go 

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

此我想要做什麼。如果該過程不存在,則創建它,然後更改正確的代碼。如果該過程確實存在,則創建失敗,並且該更新將使用新代碼更新代碼。

它爲管理員創建了一個不同的問題,因爲如果存儲過程已經存在,create會引發誤導性錯誤。當然,誤導,事實上,當期望的結果發生時,你不應該看到紅色錯誤文本。

有沒有人有辦法壓制紅色文字?我試過的所有東西都會導致'CREATE/ALTER PROCEDURE必須是查詢批處理中的第一條語句'。

+0

的可能的複製[?你怎麼在SQL Server中創建或更改做(http://stackoverflow.com/questions/1434160/what-do-you-do-in-sql -server-to-create-or-alter) – ruffin

+0

我要指出的是,如果您將權限作爲proc的一部分編寫,那麼在Drop和Create中沒有問題。如果您對proc有特殊權限,那麼它應該是存儲在源代碼庫中的腳本的一部分。然後當你去做改變時,那裏已經有了許可。 – HLGEM

回答

46

這將工作,並保持完好的權限:

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

哈。我忘記了這個訣竅。 – RBarryYoung

+0

我喜歡我的開始 - 結束。 – quillbreaker

+0

這也適用於用戶定義函數,這是我發現需要「改變」的地方,因爲這個函數被幾件事情使用。對於OP,這將是首選,恕我直言。 – granadaCoder

9

像這樣:

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 
    ') 

注:

  1. 記得在動態SQL字符串您的報價翻倍。
  2. 爲了便於閱讀,我已經縮進了它,但這也會將額外的縮進空格添加到實際的過程列表中。如果你不明白,那麼就減少動態SQL文本的縮進級別。
+0

僅供參考,我會盡量在線上發佈時添加BEGIN..ENDs。只是因爲我看到一個新手多次嘗試向其他人的SQL添加一行,但忘記添加BEGIN.END。 – RBarryYoung

+0

外來的,真的。新行上的「GO」完全覆蓋了它的範圍。怎麼說有人不會'開始...結束'並在'結束'之後但在'開始'之前放置更多的陳述?但這只是一個意見,每個人都有權獲得一個! – RichardTheKiwi

+0

@RichardTheKiwi:這是一個罕見的錯誤。 (好吧,誤解GO是一個常見的錯誤,但它通常以不同的方式表現出來,因爲變量超出了範圍)通常,我看到的沒有BEGIN..END的問題是他們會忘記它們對於分支中的多個語句是必需的/塊。當BEGIN ..END在那裏,它似乎在視覺上「提醒」他們,所以他們不會把新的線路放在塊之外。 (至少我從沒見過那個錯誤) – RBarryYoung

4

終於有一天在這其中SQL Server已實施了相當於創建或替換。他們的等價物是「創建或改變」。這從SQL Server 2016 SP1起可用。用法示例:

use [myDatabase] 
go 

Create or Alter procedure myProcedure as 
begin 
    -- procedure code here 
end 
go 
相關問題