Как мне удалить функцию, если она уже существует?

101

Я знаю, что это должно быть просто, но как мне предварять создание функции проверкой, существует ли она уже? Если он существует, я хочу отбросить и воссоздать его.

Дэвид Штайн
источник

Ответы:

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

Если вы хотите избежать использования таблиц sys *, вы можете вместо этого сделать ( отсюда в примере A):

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 есть второй параметр для типа объекта
Sparky
1
заданные имена объектов (которые появляются в sys.objects) должны быть уникальными, запрос xtype избыточен. Попробуйте создать таблицу и сохраненную процедуру с тем же именем ...
gbn,
22
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')
Спарки
источник
2
Я всегда предпочитал метод Object_id, он кажется более простым для чтения в коде. Всегда любопытно, почему сгенерированный Microsoft образец кода вместо этого использует поиск sys.objects ...
Спарки,
12

Это работает для любого объекта, а не только для функций:

IF OBJECT_ID('YourObjectName') IS NOT NULL 

затем просто добавьте свой вкус объекта, как в:

IF OBJECT_ID('YourFunction') IS NOT NULL
   DROP FUNCTION YourFunction
Метафора
источник
11

У вас есть два варианта отбросить и воссоздать процедуру в 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   
Конрад
источник
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
Фиона - myaccessible.website
источник
2

Я обычно избегаю запросов из таблиц типов sys *, поставщики обычно меняют их между выпусками, основными или другими. Что я всегда делал, так это выдавал DROP FUNCTION <name>инструкцию и не беспокоился о какой-либо ошибке SQL, которая может вернуться. Я считаю это стандартной процедурой в области DBA.

Джефф Уокер
источник
1
sys. в SQL Server 2005 это официальный способ. В настоящее время это представления, а не таблицы, и фактические таблицы sys скрыты от нас.
gbn
2

Из SQL Server 2016 CTP3вы можете использовать новые операторы DIE вместо большихIF оберток

Синтаксис:

DROP FUNCTION [IF EXISTS] {[schema_name. ] имя_функции} [, ... n]

Запрос:

DROP Function IF EXISTS udf_name

Больше информации здесь

P ரதீப்
источник
0
IF EXISTS
      (SELECT * 
      FROM schema.sys.objects
      WHERE name = 'func_name')
    DROP FUNCTION [dbo].[func_name]
GO
user2419223
источник
0

Вот мой взгляд на это:

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
источник
0

Проверьте, существует ли функция

 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

Проверьте IF Exist для сохраненной процедуры, также нажав ссылку ниже http://www.gurujipoint.com/2017/05/check-if-exist-for-trigger-function-and.html

Джатин Фулера
источник
0

Если вы хотите использовать стандарт INFORMATION_SCHEMA ISO ISO, а не специфичный для SQL Server sysobjects, вы можете сделать это:

IF EXISTS (
    SELECT ROUTINE_NAME FROM INFORMATION_SCHEMA.ROUTINES WHERE ROUTINE_NAME = N'FunctionName'
)
   DROP FUNCTION [dbo].[FunctionName]
GO
Эд Гривз
источник