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

发布于 2024-10-26 08:06:23 字数 248 浏览 2 评论 0原文

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

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

I need to find out if a function exists in a database, so that I can drop it and create it again. It should basically be something like the following code that I use for stored procedures:

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

一场春暖 2024-11-02 08:06:23

这就是 SSMS 在使用 DROP 和 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 if Exists 代替。

This is what SSMS uses when you script using the DROP and CREATE option

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 

This approach to deploying changes means that you need to recreate all permissions on the object so you might consider ALTER-ing if Exists instead.

二智少女 2024-11-02 08:06:23

我倾向于将 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' ) 

I tend to use the Information_Schema:

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

for functions, and change Routine_Type for stored procedures

IF EXISTS ( SELECT  1
            FROM    Information_schema.Routines
            WHERE   Specific_schema = 'dbo'
                    AND specific_name = 'Foo'
                    AND Routine_Type = 'PROCEDURE' ) 
梦里人 2024-11-02 08:06:23

为什么不只是:

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

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

  • FN:标量函数
  • IF:内联表值函数
  • TF:表值函数
  • FS:汇编 (CLR) 标量函数
  • FT:汇编 ( CLR) 表值函数
  • U : 表(用户定义)

Why not just:

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

The second argument of object_id is optional, but can help to identify the correct object. There are numerous possible values for this type argument, particularly:

  • FN : Scalar function
  • IF : Inline table-valued function
  • TF : Table-valued-function
  • FS : Assembly (CLR) scalar-function
  • FT : Assembly (CLR) table-valued function
  • U : Table (user-defined)
一腔孤↑勇 2024-11-02 08:06:23

我知道这个线程很旧,但我只是想为那些认为 AlterDropCreate 更安全的人添加这个答案。下面的代码将更改函数(如果存在)或创建(如果不存在):

  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
  ...

I know this thread is old but I just wanted to add this answer for those who believe it's safer to Alter than Drop and Create. The below will Alter the Function if it exists or Create it if doesn't:

  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
  ...
杀お生予夺 2024-11-02 08:06:23

我发现您可以使用一种非常不冗长且直接的方法来检查各种 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 文章。

OBJECTPROPERTY 函数使用以下签名:

OBJECTPROPERTY ( id , property ) 

将文字值传递到属性参数中,指定要查找的对象的类型。您可以提供大量的值。

I've found you can use a very non verbose and straightforward approach to checking for the existence various SQL Server objects this way:

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

This is based on the OBJECTPROPERTY function which is available in SQL 2005+. The MSDN article can be found here.

The OBJECTPROPERTY function uses the following signature:

OBJECTPROPERTY ( id , property ) 

You pass a literal value into the property parameter, designating the type of object you are looking for. There's a massive list of values you can supply.

风月客 2024-11-02 08:06:23

从 SQL Server 2016 SP1、SQL Server 2017 或更高版本中,您可以使用以下语法:

CREATE OR ALTER [object] ...

为了避免跳过这些环节。这还有一个关于持久化过程的元数据的额外好处(而不是每次更改它时都会获得一个全新的 objectid),这有时很有用,特别是当您使用 QueryStore 或其他关心 objectid 的工具时。

From SQL Server 2016 SP1, SQL Server 2017 or later, you can use the syntax:

CREATE OR ALTER [object] ...

To avoid jumping through these hoops. This has an additonal benefit of metadata about the procedure being persisted (rather than every time you change it it getting a brand new objectid) which can sometimes be useful, especially if you use things like QueryStore or other tools that care about the objectid.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文