Come faccio a eliminare una funzione se esiste già?


101

So che deve essere semplice, ma come faccio a precedere la creazione di una funzione con un controllo per vedere se esiste già? Se esiste, voglio eliminarlo e ricrearlo.

Risposte:


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 vuoi evitare le tabelle sys *, potresti invece fare (da qui nell'esempio A):

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

La cosa principale da catturare è il tipo di funzione che stai cercando di eliminare (indicato nello sql in alto da FN, IF e TF):

  • FN = Funzione scalare
  • IF = funzione tabella inline
  • TF = Funzione tabella

Ehi grazie, non sapevo che Object_id avesse un secondo parametro per il tipo di oggetto
Sparky

1
i nomi degli oggetti dati (che appaiono in sys.objects) devono essere univoci, l'interrogazione di xtype è ridondante. Prova a creare una tabella e un processo memorizzato con lo stesso nome ...
gbn

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

Puoi anche cercare il nome in sysobjects

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

In realtà, se la funzione potrebbe essere una funzione di tabella, devi usare

xtype in ('FN','TF')

2
Ho sempre preferito il metodo Object_id, sembra più semplice leggere nel codice. Sono sempre curioso di sapere perché il codice di esempio generato da Microsoft utilizza invece la ricerca sys.objects ...
Sparky

12

Funziona per qualsiasi oggetto, non solo per le funzioni:

IF OBJECT_ID('YourObjectName') IS NOT NULL 

quindi aggiungi semplicemente il tuo sapore di oggetto, come in:

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

11

Sono disponibili due opzioni per eliminare e ricreare la procedura in SQL Server 2016.

A partire da SQL Server 2016: utilizzare IF EXISTS

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

A partire da SQL Server 2016 SP1: utilizzare 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

Di solito evito le query dalle tabelle di tipo sys *, i fornitori tendono a cambiarle tra le versioni, principali o meno. Quello che ho sempre fatto è emettere la DROP FUNCTION <name>dichiarazione e non preoccuparmi di eventuali errori SQL che potrebbero ripresentarsi. Considero quella procedura standard nel regno DBA.


1
SYS. in SQL Server 2005 è il modo ufficiale. Al giorno d'oggi sono viste non tabelle e le attuali tabelle di sistema ci sono nascoste.
gbn

2

Da SQL Server 2016 CTP3è possibile utilizzare nuove istruzioni DIE invece di grandi IFwrapper

Sintassi:

FUNZIONE DROP [SE ESISTE] {[nome_schema. ] nome_funzione} [, ... n]

Query:

DROP Function IF EXISTS udf_name

Maggiori info qui


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

0

Ecco la mia opinione su questo:

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

Verificare SE esiste per la funzione

 IF  EXISTS (SELECT TOP 1 1 FROM sys.objects WHERE 
        object_id = OBJECT_ID(N'[Schema].[function_Name]')
         AND type in (N'FN', N'IF', N'TF', N'FS', N'FT'))
BEGIN
DROP FUNCTION [Schema].[function_Name]
Print('function dropped => [Schema].[function_Name]')
END
GO

Controllare IF Exist per stored procedure, funzione anche facendo clic sul collegamento sottostante http://www.gurujipoint.com/2017/05/check-if-exist-for-trigger-function-and.html


0

Se desideri utilizzare lo standard ISO di SQL INFORMATION_SCHEMA e non quello specifico di SQL Server sysobjects, puoi farlo:

IF EXISTS (
    SELECT ROUTINE_NAME FROM INFORMATION_SCHEMA.ROUTINES WHERE ROUTINE_NAME = N'FunctionName'
)
   DROP FUNCTION [dbo].[FunctionName]
GO
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.