¿Cómo elimino una función si ya existe?

101

Sé que esto debe ser simple, pero ¿cómo presento la creación de una función con una verificación para ver si ya existe? Si existe, quiero soltarlo y volver a crearlo.

DavidStein
fuente

Respuestas:

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

Si desea evitar las tablas sys *, puede hacer (desde aquí en el ejemplo A):

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

Lo principal que debe detectar es qué tipo de función está tratando de eliminar (indicado en el sql superior por FN, IF y TF):

  • FN = Función escalar
  • IF = Función de tabla en línea
  • TF = Función de tabla
adrianbanks
fuente
Hola, gracias, no sabía que Object_id tenía un segundo parámetro para el tipo de objeto
Sparky
1
los nombres de objetos dados (que aparecen en sys.objects) tienen que ser únicos, consultar xtype es redundante. Intente crear una tabla y un proceso almacenado con el mismo nombre ...
gbn
22
if object_id('FUNCTION_NAME') is not NULL
   DROP FUNCTION <name>

También puede buscar el nombre en sysobjects

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

En realidad, si la función podría ser una función de tabla, debe usar

xtype in ('FN','TF')
Sparky
fuente
2
Siempre he preferido el método Object_id, parece más sencillo de leer en el código. Siempre tengo curiosidad por saber por qué el código de muestra generado por Microsoft utiliza la búsqueda sys.objects en su lugar ...
Sparky
12

Esto funciona para cualquier objeto, no solo para funciones:

IF OBJECT_ID('YourObjectName') IS NOT NULL 

luego simplemente agregue su sabor de objeto, como en:

IF OBJECT_ID('YourFunction') IS NOT NULL
   DROP FUNCTION YourFunction
Metáfora
fuente
11

Tiene dos opciones para eliminar y volver a crear el procedimiento en SQL Server 2016.

A partir de SQL Server 2016: use IF EXISTS

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

A partir de SQL Server 2016 SP1: use OR ALTER

CREATE [ OR ALTER ] FUNCTION [ schema_name. ] function_name   
Konrad
fuente
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
fuente
2

Por lo general, evito las consultas de las tablas de tipo sys *, los proveedores tienden a cambiarlas entre versiones, principales o de otro tipo. Lo que siempre he hecho es emitir la DROP FUNCTION <name>declaración y no preocuparme por cualquier error de SQL que pueda volver. Considero ese procedimiento estándar en el ámbito de DBA.

Jeff Walker
fuente
1
sys. en SQL Server 2005 es la forma oficial. Hoy en día son vistas, no tablas y las tablas del sistema reales están ocultas para nosotros.
gbn
2

Desde SQL Server 2016 CTP3puede usar nuevas declaraciones DIE en lugar de grandes IFcontenedores

Sintaxis:

FUNCIÓN SOLTAR [SI EXISTE] {[nombre_esquema. ] nombre_función} [, ... n]

Consulta:

DROP Function IF EXISTS udf_name

Más info aquí

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

Aquí está mi opinión sobre esto:

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
fuente
0

Compruebe si existe para la función

 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

Verifique si existe para el procedimiento almacenado, función también haciendo clic en el enlace siguiente http://www.gurujipoint.com/2017/05/check-if-exist-for-trigger-function-and.html

Jatin Phulera
fuente
0

Si desea utilizar el estándar de SQL ISO INFORMATION_SCHEMA y no el específico de SQL Server sysobjects, puede hacer esto:

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