【问题标题】:How do I drop a function if it already exists?如果函数已经存在,如何删除它?
【发布时间】:2011-01-18 10:42:15
【问题描述】:

我知道这一定很简单,但是如何在创建函数之前先检查它是否已经存在?如果它存在,我想删除并重新创建它。

【问题讨论】:

    标签: tsql sql-server-2000


    【解决方案1】:

    您有两个选项可以在 SQL Server 2016 中删除和重新创建过程。

    从 SQL Server 2016 开始 - 使用 IF EXISTS

    DROP FUNCTION [ IF EXISTS ] { [ schema_name. ] function_name } [ ,...n ]   [;]
    

    从 SQL Server 2016 SP1 开始 - 使用 OR ALTER

    CREATE [ OR ALTER ] FUNCTION [ schema_name. ] function_name   
    

    【讨论】:

      【解决方案2】:

      这适用于任何对象,而不仅仅是函数:

      IF OBJECT_ID('YourObjectName') IS NOT NULL 
      

      然后只需添加您喜欢的对象,如下所示:

      IF OBJECT_ID('YourFunction') IS NOT NULL
         DROP FUNCTION YourFunction
      

      【讨论】:

        【解决方案3】:

        如果您想使用 SQL ISO 标准 INFORMATION_SCHEMA 而不是 SQL Server 特定的sysobjects,您可以这样做:

        IF EXISTS (
            SELECT ROUTINE_NAME FROM INFORMATION_SCHEMA.ROUTINES WHERE ROUTINE_NAME = N'FunctionName'
        )
           DROP FUNCTION [dbo].[FunctionName]
        GO
        

        【讨论】:

          【解决方案4】:

          这是我的看法:

          if(object_id(N'[dbo].[fn_Nth_Pos]', N'FN')) is not null
              drop function [dbo].[fn_Nth_Pos];
          GO
          CREATE FUNCTION [dbo].[fn_Nth_Pos]
          (
              @find char, --char to find
              @search varchar(max), --string to process   
              @nth int --occurrence   
          )
          RETURNS int
          AS
          BEGIN
              declare @pos int --position of nth occurrence
              --init
              set @pos = 0
          
              while(@nth > 0)
              begin       
                  set @pos = charindex(@find,@search,@pos+1)
                  set @nth = @nth - 1
              end 
          
              return @pos
          END
          GO
          
          --EXAMPLE
          declare @files table(name varchar(max));
          
          insert into @files(name) values('abc_1_2_3_4.gif');
          insert into @files(name) values('zzz_12_3_3_45.gif');
          
          select
              f.name,
              dbo.fn_Nth_Pos('_', f.name, 1) as [1st],
              dbo.fn_Nth_Pos('_', f.name, 2) as [2nd],
              dbo.fn_Nth_Pos('_', f.name, 3) as [3rd],
              dbo.fn_Nth_Pos('_', f.name, 4) as [4th]
          from 
              @files f;
          

          【讨论】:

            【解决方案5】:

            SQL Server 2016 CTP3 开始,您可以使用新的DIE 语句代替大的IF 包装器

            语法:

            删除函数 [ 如果存在 ] { [ schema_name. ] 函数名 } [ ,...n ]

            查询:

            DROP Function IF EXISTS udf_name
            

            更多信息here

            【讨论】:

              【解决方案6】:
              IF EXISTS
                    (SELECT * 
                    FROM schema.sys.objects
                    WHERE name = 'func_name')
                  DROP FUNCTION [dbo].[func_name]
              GO
              

              【讨论】:

                【解决方案7】:
                IF EXISTS (
                    SELECT * FROM sysobjects WHERE id = object_id(N'function_name') 
                    AND xtype IN (N'FN', N'IF', N'TF')
                )
                    DROP FUNCTION function_name
                GO
                

                如果你想避免使用 sys* 表,你可以这样做(来自示例 A 中的 here):

                IF object_id(N'function_name', N'FN') IS NOT NULL
                    DROP FUNCTION function_name
                GO
                

                要抓住的主要是您要删除的函数类型(在顶部 sql 中用 FN、IF 和 TF 表示):

                • FN = 标量函数
                • IF = 内联表函数
                • TF = 表函数

                【讨论】:

                • 嘿,谢谢,我不知道 Object_id 有第二个对象类型的参数
                • 给定的对象名称(出现在 sys.objects 中)必须是唯一的,查询 xtype 是多余的。尝试创建同名的表和存储过程...
                【解决方案8】:
                IF EXISTS 
                (SELECT * FROM sys.objects 
                WHERE object_id = OBJECT_ID(N'functionName') 
                AND type in (N'FN', N'IF', N'TF', N'FS', N'FT'))
                
                DROP FUNCTION functionName
                GO
                

                【讨论】:

                  【解决方案9】:

                  我通常回避来自 sys* 类型表的查询,供应商倾向于在主要版本或其他版本之间更改这些。我一直做的是发出DROP FUNCTION <name> 语句,而不用担心可能会再次出现任何SQL 错误。我认为这是 DBA 领域的标准程序。

                  【讨论】:

                  • 系统。在 SQL Server 2005 中是官方的方式。它们现在是 视图 而不是表,实际的 sys 表对我们是隐藏的。
                  【解决方案10】:
                  if object_id('FUNCTION_NAME') is not NULL
                     DROP FUNCTION <name>
                  

                  您也可以在 sysobjects 中查找名称

                  IF EXISTS (SELECT * 
                         FROM   sysobjects 
                             WHERE name='<function name>' and xtype='FN'
                  

                  其实,如果函数可以是表函数,你需要使用

                  xtype in ('FN','TF')
                  

                  【讨论】:

                  • 我一直更喜欢 Object_id 方法,在代码中阅读起来似乎更简单。总是好奇为什么微软生成的示例代码使用 sys.objects 查找来代替......
                  猜你喜欢
                  • 2018-03-15
                  • 2021-09-29
                  • 2014-03-02
                  • 2021-07-24
                  • 2010-12-03
                  • 2011-04-19
                  • 2016-07-16
                  • 2021-12-02
                  • 2017-10-29
                  相关资源
                  最近更新 更多