Jak usunąć funkcję, jeśli już istnieje?


101

Wiem, że to musi być proste, ale jak poprzedzić tworzenie funkcji sprawdzeniem, czy już istnieje? Jeśli istnieje, chcę go usunąć i odtworzyć.

Odpowiedzi:


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

Jeśli chcesz uniknąć tabel sys *, możesz zamiast tego zrobić ( stąd w przykładzie A):

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

Najważniejszą rzeczą do wyłapania jest rodzaj funkcji, którą próbujesz usunąć (oznaczoną w górnym sql przez FN, IF i TF):

  • FN = funkcja skalarna
  • IF = funkcja tabeli wbudowanej
  • TF = funkcja tabeli

Hej, dzięki, nie wiedziałem, że Object_id ma drugi parametr dla typu obiektu
Sparky,

1
podane nazwy obiektów (które pojawiają się w sys.objects) muszą być unikalne, odpytywanie xtype jest zbędne. Spróbuj utworzyć tabelę i przechowywany proces o tej samej nazwie ...
gbn

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

Możesz również sprawdzić nazwę w sysobjects

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

Właściwie, jeśli funkcja może być funkcją tabeli, musisz użyć

xtype in ('FN','TF')

2
Zawsze wolałem metodę Object_id, odczytanie jej w kodzie wydaje się prostsze. Zawsze ciekawi, dlaczego wygenerowany przez firmę Microsoft przykładowy kod używa zamiast tego wyszukiwania sys.objects ...
Sparky

12

Działa to dla każdego obiektu, nie tylko funkcji:

IF OBJECT_ID('YourObjectName') IS NOT NULL 

następnie po prostu dodaj swój smak obiektu, jak w:

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

11

Masz dwie opcje upuszczenia i ponownego utworzenia procedury w programie SQL Server 2016.

Począwszy od SQL Server 2016 - użyj IF EXISTS

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

Począwszy od dodatku SP1 dla programu SQL Server 2016 - użyj 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

Zwykle unikam zapytań z tabel typu sys *, dostawcy mają tendencję do zmieniania ich między wydaniami, głównymi lub innymi. Zawsze robiłem, aby wydać DROP FUNCTION <name>instrukcję i nie martwić się o żaden błąd SQL, który może powrócić. Uważam tę standardową procedurę w dziedzinie DBA.


1
sys. w SQL Server 2005 jest oficjalnym sposobem. Obecnie są to widoki, a nie tabele, a rzeczywiste tabele sys są przed nami ukryte.
gbn

2

Od SQL Server 2016 CTP3można korzystać z nowych Die oświadczenia zamiast dużychIF owijarki

Składnia:

FUNKCJA DROP [JEŚLI ISTNIEJE] {[schema_name. ] nazwa_funkcji} [, ... n]

Pytanie:

DROP Function IF EXISTS udf_name

Więcej informacji tutaj


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

0

Oto moje podejście do tego:

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

Jeśli chcesz używać standardu SQL ISO INFORMATION_SCHEMA, a nie specyficznego dla programu SQL Server sysobjects, możesz to zrobić:

IF EXISTS (
    SELECT ROUTINE_NAME FROM INFORMATION_SCHEMA.ROUTINES WHERE ROUTINE_NAME = N'FunctionName'
)
   DROP FUNCTION [dbo].[FunctionName]
GO
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.