Comment supprimer une fonction si elle existe déjà?


101

Je sais que cela doit être simple, mais comment faire précéder la création d'une fonction par une vérification pour voir si elle existe déjà? S'il existe, je veux le supprimer et le recréer.

Réponses:


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 vous voulez éviter les tables sys *, vous pouvez à la place faire (à partir d' ici dans l'exemple A):

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

La principale chose à attraper est le type de fonction que vous essayez de supprimer (indiqué dans le sql supérieur par FN, IF et TF):

  • FN = Fonction scalaire
  • IF = fonction de tableau en ligne
  • TF = Fonction de table

Hé merci, je ne savais pas que Object_id avait un deuxième paramètre pour le type d'objet
Sparky

1
les noms d'objet donnés (qui apparaissent dans sys.objects) doivent être uniques, l'interrogation de xtype est redondante. Essayez de créer une table et un processus stocké avec le même nom ...
gbn

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

Vous pouvez également rechercher le nom dans sysobjects

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

En fait, si la fonction peut être une fonction de table, vous devez utiliser

xtype in ('FN','TF')

2
J'ai toujours préféré la méthode Object_id, elle semble plus simple à lire dans le code. Toujours curieux de savoir pourquoi l'exemple de code généré par Microsoft utilise la recherche sys.objects à la place ...
Sparky

12

Cela fonctionne pour n'importe quel objet, pas seulement pour les fonctions:

IF OBJECT_ID('YourObjectName') IS NOT NULL 

puis ajoutez simplement votre saveur d'objet, comme dans:

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

11

Vous avez deux options pour supprimer et recréer la procédure dans SQL Server 2016.

À partir de SQL Server 2016 - utilisation IF EXISTS

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

À partir de SQL Server 2016 SP1 - utilisation 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

J'évite généralement les requêtes des tables de type sys *, les vendeurs ont tendance à les changer entre les versions, majeures ou non. Ce que j'ai toujours fait, c'est d'émettre la DROP FUNCTION <name>déclaration et de ne pas m'inquiéter d'une erreur SQL qui pourrait revenir. Je considère cette procédure standard dans le domaine DBA.


1
sys. dans SQL Server 2005 est la manière officielle. Ce sont des vues et non des tables de nos jours et les tables sys réelles nous sont cachées.
gbn

2

De SQL Server 2016 CTP3vous pouvez utiliser de nouvelles instructions DIE au lieu de grandesIF wrappers

Syntaxe:

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

Requete:

DROP Function IF EXISTS udf_name

Plus d'infos ici


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

0

Voici mon point de vue sur ceci:

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

Si vous souhaitez utiliser la norme SQL ISO INFORMATION_SCHEMA et non la norme SQL Server sysobjects, vous pouvez le faire:

IF EXISTS (
    SELECT ROUTINE_NAME FROM INFORMATION_SCHEMA.ROUTINES WHERE ROUTINE_NAME = N'FunctionName'
)
   DROP FUNCTION [dbo].[FunctionName]
GO
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.