2013-09-30 35 views
2

我正在寫一個數據庫更新腳本基本上從數據庫中檢索當前的版本號,然後創建了一些存儲過程如果版本是有效的有條件創建存儲過程。如果當前版本與預期版本不匹配,那麼它應該跳過執行代碼。使用TSQL

但是我在編寫腳本時遇到了一個問題,因爲CREATE PROCEDURE必須是批處理中的第一條語句,所以我無法在創建過程語句之前插入if .. else語句。

我也使用GOTO嘗試,但都無濟於事,因爲GOTO不能跨多個批次跨越。同樣的事情適用於RETURN和RAISEERROR - 其餘的代碼仍然會執行。

示例腳本:

IF @Version = '1.0' --doesn't work 
BEGIN 
    CREATE PROCEDURE dbo.uspCreateAccount 
    AS BEGIN 
    --The rest of the code goes here 
    END 
END 

任何人都可以提供這方面的一些見解?

回答

4

您可以使用exec功能做到這一點。

IF @Version = '1.0' 
BEGIN 
    --Drop it if it already exists 
    IF OBJECT_ID('uspCreateAccount', 'P') IS NOT NULL 
     EXEC ('DROP PROCEDURE uspCreateAccount') 
    --Recreate it. 
    EXEC(' 
      CREATE PROCEDURE uspCreateAccount 
      AS BEGIN 
      --The rest of the code goes here 
      END 
    ') 
END 
+0

看起來不錯。將嘗試一下。謝謝! – user1928346

4

您可以使用exec到一個新的作用域運行SQL命令。即使dbo.YourProc已經存在,以下片段也會運行,因爲在這種情況下,exec()中的SQL命令將永遠不會被解析。

if not exists (select * from sys.procedures where name = 'YourProc') 
    exec ('create procedure dbo.YourProc as select 1 as a') 
go 
alter procedure dbo.YourProc 
as 
select ... 

如果該過程不存在,此構造會創建一個空的存根過程。如果該過程存在,則運行alter。因此它保留了程序上已經授予的權利。

+0

對不起,但這並不完全是我想要的。我所要求的是如果版本不正確,那麼不要創建程序。 – user1928346

+0

查看@ cbeckner的回答。將實際主體放在'exec'內更難以閱讀和維護,因此我試圖避免這種情況,例如通過在不同的數據庫調用中檢查版本。 – Andomar

+0

是的,他的解決方案似乎工作。想知道有沒有更好的解決方案?因爲如果我使用這種方法,可維護性成爲一個問題。 – user1928346