2013-08-26 84 views
5

我過去使用下面的存儲過程的部署腳本的一部分的首選方式:什麼是確定的存儲過程中是否存在

IF NOT EXISTS (SELECT * FROM sys.objects O 
    WHERE O.[object_id] = OBJECT_ID(N'[dbo].[SPROC_NAME]') 
    AND OBJECTPROPERTY(O.[object_id],N'IsProcedure') = 1) 

    EXEC('CREATE PROCEDURE [dbo].[SPROC_NAME] AS') 
GO 

ALTER PROCEDURE [dbo].[SPROC_NAME] 
AS 
BEGIN ... 

我不知道超載至OBJECT_ID,這需要鍵入對象ID查找,例如:

OBJECT_ID(N'[dbo].[SPROC_NAME]', N'P') 

好像使用過載將使OBJECTPROPERTY查找不必要的。

我想知道是否有任何缺點,只使用OBJECT_ID過載和刪除OBJECTPROPERTY查找。

+1

SQL對象都共享相同的唯一名稱空間。 'OBJECT_ID'返回具有該名稱的對象的ID(如果存在)。 'OBJECTPROPERTY'確認該對象實際上是一個存儲過程,因爲可能有一個名爲'[SPROC_NAME]'的表或視圖(如果存在的話,您將無法創建具有該名稱的存儲過程)。 – RBarryYoung

+0

如果指定了第二個參數,則只有該類型的對象存在時,「OBJECT_ID」纔會返回非空值。 (確保指定模式,不知道如果它是一個模式中的表和另一個模式中的過程會發生什麼......) –

回答

3

我更喜歡這種形式,並使用OBJECT*元數據功能儘可能已經停止,因爲they can block even at loose isolation levels

IF NOT EXISTS 
(
    SELECT 1 FROM sys.procedures AS p 
    INNER JOIN sys.schemas AS s 
    ON p.[schema_id] = s.[schema_id] 
    WHERE p.name = N'Procedure_Name' AND s.name = N'dbo' 
) 
BEGIN 
    EXEC sp_executesql N'CREATE PROCEDURE dbo.Procedure_Name AS'; 
END 
+0

+1。我傾向於下降,如果他們已經存在,然後重新創建,只是爲了確保我總是得到最新版本... –

+0

@Mitch CREATE存根允許真正的身體始終是一個ALTER,即使過程不存在,所以它不一定都是動態SQL。 –

+0

好點。 ... –

0

my $ .02 -

使用帶2nd參數的object_id方法。它使代碼更易於閱讀。

+0

'sys.objects'既不是系統表也不是向後兼容性視圖。它是一個目錄視圖,我認爲'OBJECT_ID()'是否易於閱讀是非常主觀的,不用擔心許多這樣的元數據函數不遵守隔離級別的語義(即,即使您設置了read_uncommitted或snapshot )。 –

1

你的情況可能是有點短:

IF OBJECT_DEFINITION(OBJECT_ID('dbo.Procedure_Name', 'P')) IS NULL 
    BEGIN 
     EXEC sys.sp_executesql 'CREATE PROCEDURE dbo.Procedure_Name AS' 
    END 

另一種方式:

IF OBJECT_ID('dbo.Procedure_Name', 'P') IS NULL 
    BEGIN 
     EXEC sys.sp_executesql 'CREATE PROCEDURE dbo.Procedure_Name AS' 
    END 
1

我最喜歡的方式是:

if object_id('x') is not null 
    begin 
    drop procedure x 
    end 
    go 
    create procedure x ... 
    ... 
相關問題