Mise à jour de janvier 2017 - SQL Server 2016+ / Azure SQL Database
SQL Server 2016 et la version actuelle d'Azure SQL Database ont désormais la syntaxe suivante pour les fonctions, procédures, tables, bases de données, etc. ( DROP IF EXISTS
):
DROP FUNCTION IF EXISTS dbo.fn_myfunc;
Et SQL Server 2016 Service Pack 1 ajoute des fonctionnalités encore meilleures pour les modules (fonctions, procédures, déclencheurs, vues), ce qui signifie aucune perte d'autorisations ou de dépendances ( CREATE OR ALTER
):
CREATE OR ALTER FUNCTION dbo.fn_myfunc ...
Ces deux améliorations de la syntaxe peuvent conduire à des scripts beaucoup plus simples utilisés pour le contrôle des sources, les déploiements, etc.
Mais si vous utilisez ...
Versions plus anciennes
Vous devez faire ce que fait SQL Server lorsque vous créez un script à partir de Management Studio:
IF NOT EXISTS (SELECT 1 FROM sys.objects WHERE type = 'FN' AND name = 'fn_myfunc')
BEGIN
DECLARE @sql NVARCHAR(MAX);
SET @sql = N'CREATE FUNCTION ...';
EXEC sp_executesql @sql;
END
Ou vous pouvez dire:
BEGIN TRY
DROP FUNCTION dbo.fn_myfunc;
END TRY
BEGIN CATCH
PRINT 'Function did not exist.';
END CATCH
GO
CREATE FUNCTION...
Ou vous pouvez simplement dire:
DROP FUNCTION dbo.fn_myfunc;
GO
CREATE FUNCTION...
(Ici, vous obtiendrez un message d'erreur si la fonction n'existe pas déjà, mais le script continuera à partir du prochain GO, donc que la suppression ait fonctionné ou non, la fonction sera toujours (re) créée.)
Notez que si vous supprimez la fonction et la recréez, vous perdrez également les autorisations et potentiellement les informations de dépendance.
L'erreur est assez explicite. Il y a deux façons de le réparer.
Séparez le script en différents lots dans Management Studio à l'aide du
GO
pseudo-mot clé etDROP
/ deCREATE
l'objet. (Notez que le mot clé lui-même peut être modifié dans les options de Management Studio, mais il s'agit du paramètre de facto, je suggère donc de le laisser seul).Lorsque vous exécutez un script (ou la partie sélectionnée d'un script), Management Studio sépare chaque bloc de script entre
GO
s et envoie séquentiellement les parties à SQL Server sous forme de lots distincts.Utilisez SQL dynamique pour envoyer un lot distinct à partir d'un autre lot.
Il s'agit de la méthode préférée, car votre script ne dépend pas alors des fonctionnalités externes pour s'exécuter correctement. Par exemple, si votre application dispose d'un programme de mise à jour de base de données, d'une manière générale, elle charge un fichier de script puis l'exécute sur le serveur cible. Vous devrez soit ajouter une logique pour séparer les lots comme le fait Management Studio (remarque: lourde de risques), soit écrire le script de manière à ce que l' ensemble du script puisse être exécuté avec succès en un seul lot.
Comme mentionné dans une autre réponse, vous pouvez faire un test / en
CREATE
utilisant cette méthode (ou une autre combinaison deDROP
/CREATE
, etc.). Ce que je préfère faire, c'est créer un objet stub si l'objet n'existe pas, puis utiliserALTER <object>
pour réellement faire la création ou la modification. Cette approche ne supprime pas les dépendances, telles que les autorisations ou les propriétés étendues, et il n'est pas nécessaire de copier / coller la logique sujette aux erreurs pour effectuer leCREATE
/ALTER
dans une seule instruction.Voici le modèle que j'utilise pour créer ou modifier une fonction scalaire. Je le laisserai comme un exercice au lecteur pour l'adapter à d'autres types d'objets (procs stockés, triggers, etc.).
la source
GO
garantit que le script se cassera, car leIF
ne mènera nulle part.DROP
/CREATE
scénario - édité. Merci.Vous avez la possibilité de vérifier si l'objet existe dans le
database
et de créer sinon:la source