2011-03-24 21 views
100

我需要確定數據庫中是否存在函數,以便我可以刪除它並重新創建它。它應該基本上是類似下面的代碼,我使用的存儲過程:如何檢查SQL數據庫上是否存在某個函數

IF EXISTS (
    SELECT * 
    FROM dbo.sysobjects 
    WHERE id = OBJECT_ID(N'[dbo].[SP_TEST]') 
      AND OBJECTPROPERTY(id, N'IsProcedure') = 1) 

回答

153

這是SSMS使用DROP and CREATE選項,當您的腳本使用

IF EXISTS (SELECT * 
      FROM sys.objects 
      WHERE object_id = OBJECT_ID(N'[dbo].[foo]') 
        AND type IN (N'FN', N'IF', N'TF', N'FS', N'FT')) 
    DROP FUNCTION [dbo].[foo] 

GO 

這種方式部署的變化意味着你需要重新創建對象的所有權限,因此您可能會考慮使用ALTER -ing,如果存在,則改爲。

+15

讓我不知道**更加**爲什麼[沒有一個sys.functions(HTTP://計算器。 com/questions/468672/sql-server-where-is-sys-functions)系統目錄視圖..... – 2011-03-24 12:33:57

+1

感謝Martin,你的回答是現貨! – 2011-03-24 12:47:53

42

我傾向於使用INFORMATION_SCHEMA:

IF EXISTS (SELECT 1 
      FROM Information_schema.Routines 
      WHERE Specific_schema = 'dbo' 
        AND specific_name = 'Foo' 
        AND Routine_Type = 'FUNCTION') 

的功能,並改變Routine_Type存儲過程

IF EXISTS (SELECT 1 
      FROM Information_schema.Routines 
      WHERE Specific_schema = 'dbo' 
        AND specific_name = 'Foo' 
        AND Routine_Type = 'PROCEDURE') 
+2

酷我正在尋找這樣的東西,永遠找不到它。我相信最好總體使用information_schema,因爲它不與特定的RDBMS綁定。 (順便說一句跨平臺兼容來自這個答案:http://stackoverflow.com/a/14290099/420667) – user420667 2015-11-04 20:36:32

+0

這應該是被接受的答案。 – Crono 2017-09-01 21:52:11

9

我發現你可以使用一個非常不詳細,直觀的方法來檢查對於存在各種SQL Server對象的方式如下:

IF OBJECTPROPERTY (object_id('schemaname.scalarfuncname'), 'IsScalarFunction') = 1 
IF OBJECTPROPERTY (object_id('schemaname.tablefuncname'), 'IsTableFunction') = 1 
IF OBJECTPROPERTY (object_id('schemaname.procname'), 'IsProcedure') = 1 

這基於SQL 2005+中提供的OBJECTPROPERTY函數。 MSDN文章可以找到here

的OBJECTPROPERTY函數使用以下簽名:

OBJECTPROPERTY (id , property) 

你傳遞一個文本值到屬性參數,指定對象的您正在尋找的類型。你可以提供一個巨大的價值清單。

+0

我認爲如果它包含完整的if/drop示例,可以更容易地看到此答案的簡單性。 – Jonathan 2017-05-18 18:26:21

11

爲什麼不乾脆:

IF object_id('YourFunctionName') IS NOT NULL 
BEGIN 
    DROP FUNCTION [dbo].[YourFunctionName] 
END 
GO 

至少,這對我的作品..

+0

酷!清晰而簡單。在大多數情況下都可以接受。 – 2016-03-03 11:59:30

+3

從技術上講,這可能會失敗,因爲它只檢查是否存在該名稱的對象。不是說有一個對象,而是一個功能。例如。如果'CREATE TABLE YourFunctionName(X INT);'然後運行代碼將失敗。 – 2016-05-06 13:45:01

+0

@MartinSmith:易於製作。只需使用object_id('YourFunction','FN')或任何其他指示符(第二個參數)來清楚指明您指的是哪種對象。 – darlove 2017-09-20 13:38:24

1

我知道這個線程是舊的,但我只是想補充這個答案對於那些誰相信它比更安全AlterDropCreate。如果沒有在下面將AlterFunction如果存在或Create它:

IF NOT EXISTS (SELECT * 
       FROM sys.objects 
       WHERE object_id = OBJECT_ID(N'[dbo].[foo]') 
         AND type IN (N'FN', N'IF', N'TF', N'FS', N'FT')) 
     EXEC('CREATE FUNCTION [dbo].[foo]() RETURNS INT AS BEGIN RETURN 0 END') 
    GO 
    ALTER PROCEDURE [dbo].[foo] 
    AS 
    ... 
相關問題