如何检查SQL数据库上是否存在函数


138

我需要找出数据库中是否存在函数,以便可以删除它并再次创建它。它基本上应该类似于我用于存储过程的以下代码:

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

Answers:


206

这是使用DROP and CREATE选项编写脚本时SSMS所使用的

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(如果存在)。


17
使我不知道为什么没有一个sys.functions系统目录视图.....
marc_s

61

我倾向于使用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绑定。(顺便说一句,跨平台兼容的概念来自此答案:stackoverflow.com/a/14290099/420667
user420667 2015年

40

为什么不只是:

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

的第二个参数object_id是可选的,但可以帮助识别正确的对象。此类型参数有很多可能的值,尤其是:

  • FN:标量函数
  • IF:内联表值函数
  • TF:表值函数
  • FS:汇编(CLR)标量函数
  • FT:装配(CLR)表值函数

4
从技术上讲,这可能会失败,因为它只会检查是否存在该名称的对象。并不是说有一个对象,而是一个函数。EG如果CREATE TABLE YourFunctionName(X INT);那么运行代码将失败。
马丁·史密斯

1
@MartinSmith:易于制作。只需使用object_id('YourFunction', 'FN')或任何其他可以清楚地表明您所指的对象的指示符(第二个参数)即可。
darlove

@darlove使用'FN'作为第二个参数可能不起作用。我刚刚学到的。“ FN”表示标量函数。该链接告诉您可以传递sqlhints.com/tag/how-to-check-if-function-exists的不同参数值。我一直使用“ FN”来检查现有的表值函数,但是它不起作用。我必须使用“TF”
user12345

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

这是基于OBJECTPROPERTY函数的,该函数在SQL 2005+中可用。您可以在此处找到MSDN文章。

OBJECTPROPERTY函数使用以下签名:

OBJECTPROPERTY ( id , property ) 

您将一个文字值传递给property参数,以指定要查找的对象的类型。您可以提供大量的价值清单。


我认为,如果包含完整的if / drop示例,将更容易看到此答案的简单性。
乔纳森

6

我知道这个线程很旧,但我只想为那些认为AlterDropand 更安全的人添加这个答案Create。下面将Alter显示Function它是否存在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 FUNCTION [dbo].[foo]
  AS
  ...

2
我喜欢这个,但我认为应该是“ ALTER FUNCTION”,不是吗?
Erik

我喜欢ALTER OR CREATE
AgentFire
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.