Wie lösche ich eine Funktion, wenn sie bereits vorhanden ist?

100

Ich weiß, dass dies einfach sein muss, aber wie kann ich der Erstellung einer Funktion eine Prüfung voranstellen, um festzustellen, ob sie bereits vorhanden ist? Wenn es existiert, möchte ich es löschen und neu erstellen.

DavidStein
quelle

Antworten:

186
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

Wenn Sie die sys * -Tabellen vermeiden möchten, können Sie stattdessen Folgendes tun (von hier in Beispiel A):

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

Die Hauptsache ist, welche Art von Funktion Sie löschen möchten (im obersten SQL mit FN, IF und TF gekennzeichnet):

  • FN = Skalarfunktion
  • IF = Inlined Table Function
  • TF = Tabellenfunktion
adrianbanks
quelle
Hey danke, ich wusste nicht, dass Object_id einen zweiten Parameter für den Objekttyp hat
Sparky
1
Vorgegebene Objektnamen (die in sys.objects angezeigt werden) müssen eindeutig sein. Das Abfragen von xtype ist redundant. Versuchen Sie, eine Tabelle und einen gespeicherten Prozess mit demselben Namen zu
erstellen
22
if object_id('FUNCTION_NAME') is not NULL
   DROP FUNCTION <name>

Sie können den Namen auch in sysobjects nachschlagen

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

Wenn die Funktion eine Tabellenfunktion sein könnte, müssen Sie sie tatsächlich verwenden

xtype in ('FN','TF')
Sparky
quelle
2
Ich habe immer die Object_id-Methode bevorzugt, es scheint einfacher zu sein, den Code einzulesen. Immer neugierig, warum der von Microsoft generierte Beispielcode stattdessen die Suche nach sys.objects verwendet ...
Sparky
12

Dies funktioniert für jedes Objekt, nicht nur für Funktionen:

IF OBJECT_ID('YourObjectName') IS NOT NULL 

Fügen Sie dann einfach Ihren Objektgeschmack hinzu, wie in:

IF OBJECT_ID('YourFunction') IS NOT NULL
   DROP FUNCTION YourFunction
Metapher
quelle
11

Sie haben zwei Möglichkeiten, die Prozedur in SQL Server 2016 zu löschen und neu zu erstellen.

Ab SQL Server 2016 - verwenden IF EXISTS

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

Ab SQL Server 2016 SP1 - verwenden OR ALTER

CREATE [ OR ALTER ] FUNCTION [ schema_name. ] function_name   
Konrad
quelle
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
Fiona - myaccessible.website
quelle
2

Normalerweise scheue ich mich vor Abfragen aus Tabellen vom Typ sys *. Anbieter neigen dazu, diese zwischen Hauptversionen, Hauptversionen oder auf andere Weise, zu ändern. Was ich immer getan habe, ist, die DROP FUNCTION <name>Anweisung auszugeben und mich nicht um einen SQL-Fehler zu sorgen, der möglicherweise erneut auftritt. Ich betrachte dieses Standardverfahren im DBA-Bereich.

Jeff Walker
quelle
1
sys. in SQL Server 2005 ist der offizielle Weg. Sie sind heutzutage Ansichten, keine Tabellen, und die tatsächlichen Systemtabellen sind uns verborgen.
Gbn
2

Von können SQL Server 2016 CTP3Sie neue DIE- Anweisungen anstelle von großen IFWrappern verwenden

Syntax :

DROP-FUNKTION [WENN EXISTIERT] {[Schemaname. ] Funktionsname} [, ... n]

Abfrage:

DROP Function IF EXISTS udf_name

Mehr Infos hier

P ரதீப்
quelle
0
IF EXISTS
      (SELECT * 
      FROM schema.sys.objects
      WHERE name = 'func_name')
    DROP FUNCTION [dbo].[func_name]
GO
user2419223
quelle
0

Hier ist meine Meinung dazu:

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;
Alex
quelle
0

Überprüfen Sie, ob die Funktion vorhanden ist

 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

Überprüfen Sie, ob eine gespeicherte Prozedur vorhanden ist, und klicken Sie auf den folgenden Link: http://www.gurujipoint.com/2017/05/check-if-exist-for-trigger-function-and.html

Jatin Phulera
quelle
0

Wenn Sie den SQL-ISO-Standard INFORMATION_SCHEMA und nicht den SQL Server-spezifischen Standard verwenden möchten sysobjects, können Sie Folgendes tun:

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