Como elimino uma função se ela já existe?


101

Eu sei que isso deve ser simples, mas como prefácio a criação de uma função com uma verificação para ver se ela já existe? Se ele existir, quero descartá-lo e recriá-lo.

Respostas:


187
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

Se quiser evitar as tabelas sys *, você pode fazer (a partir daqui no exemplo A):

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

A principal coisa a detectar é o tipo de função que você está tentando excluir (denotado no sql superior por FN, IF e TF):

  • FN = Função Escalar
  • IF = Função de tabela embutida
  • TF = Função da Tabela

Ei, obrigado, eu não sabia que Object_id tinha um segundo parâmetro para o tipo de objeto
Sparky de

1
determinados nomes de objeto (que aparecem em sys.objects) devem ser exclusivos, consultar xtype é redundante. Tente criar uma tabela e um procedimento armazenado com o mesmo nome ...
gbn

22
if object_id('FUNCTION_NAME') is not NULL
   DROP FUNCTION <name>

Você também pode procurar o nome em sysobjects

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

Na verdade, se a função pode ser uma função de tabela, você precisa usar

xtype in ('FN','TF')

2
Sempre preferi o método Object_id, parece mais simples de ler no código. Sempre curioso por que o código de amostra gerado pela Microsoft usa a pesquisa sys.objects em vez disso ...
Sparky

12

Isso funciona para qualquer objeto, não apenas funções:

IF OBJECT_ID('YourObjectName') IS NOT NULL 

em seguida, basta adicionar o sabor do objeto, como em:

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

11

Você tem duas opções para descartar e recriar o procedimento no SQL Server 2016.

A partir do SQL Server 2016 - use IF EXISTS

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

A partir do SQL Server 2016 SP1 - use OR ALTER

CREATE [ OR ALTER ] FUNCTION [ schema_name. ] function_name   

6
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

2

Eu geralmente evito consultas em tabelas do tipo sys *, os fornecedores tendem a alterá-las entre os lançamentos, principais ou não. O que sempre fiz é emitir a DROP FUNCTION <name>instrução e não me preocupar com nenhum erro de SQL que possa retornar. Considero esse procedimento padrão no domínio DBA.


1
sys. no SQL Server 2005 é a forma oficial. Eles são visualizações, não tabelas hoje em dia, e as tabelas reais do sistema estão ocultas de nós.
gbn

2

De SQL Server 2016 CTP3você pode usar novas instruções DIE em vez de grandes IFinvólucros

Sintaxe:

DROP FUNCTION [IF EXISTS] {[schema_name. ] nome_da_função} [, ... n]

Inquerir:

DROP Function IF EXISTS udf_name

Mais informações aqui


0
IF EXISTS
      (SELECT * 
      FROM schema.sys.objects
      WHERE name = 'func_name')
    DROP FUNCTION [dbo].[func_name]
GO

0

Aqui está minha opinião sobre isso:

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;


0

Se quiser usar o padrão SQL ISO INFORMATION_SCHEMA e não o específico do SQL Server sysobjects, você pode fazer isso:

IF EXISTS (
    SELECT ROUTINE_NAME FROM INFORMATION_SCHEMA.ROUTINES WHERE ROUTINE_NAME = N'FunctionName'
)
   DROP FUNCTION [dbo].[FunctionName]
GO
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.