web-dev-qa-db-fra.com

déposer le déclencheur s'il existe et créer

Je voudrais vérifier si le déclencheur existe sur [tbl] et en créer un autre. J'ai essayé de cette façon mais je n'ai pas fonctionné. Qu'est-ce que je fais mal?

IF EXISTS (SELECT * FROM sys.objects WHERE [name] = '[dbo].[trg]' AND [type] = 'TR')
      DROP TRIGGER [dbo].[trg] ON [dbo].[tbl]
GO
CREATE TRIGGER [dbo].[trg] ON [dbo].[tbl] 
AFTER DELETE
AS
BEGIN
   //
END
GO
14
user3399326

Le champ [name] dans sys.objects ne contiendra que le nom réel (i.e. trg), not y compris le schéma (i.e. dbo dans ce cas) ou tout qualificateur de texte (i.e. [ et ] dans ce cas).

ET, vous ne spécifiez pas le nom de la table pour DROP TRIGGER car le déclencheur est un objet en soi (contrairement aux index). Vous devez donc supprimer la clause ON (utilisée uniquement avec les déclencheurs DDL et Logon).

IF EXISTS (SELECT * FROM sys.objects WHERE [name] = N'trg' AND [type] = 'TR')
BEGIN
      DROP TRIGGER [dbo].[trg];
END;

Veuillez noter que vous devez préfixer le littéral de chaîne de nom d'objet avec un N puisque le champ [name] est un type de données sysname qui équivaut à NVARCHAR(128).

Si vous souhaitez incorporer le nom du schéma, vous pouvez utiliser la fonction OBJECT_ID() qui autorise les noms de schéma et les qualificateurs de texte (vous devrez alors faire correspondre le code avec object_id au lieu de name):

IF EXISTS (SELECT * FROM sys.objects WHERE [object_id] = OBJECT_ID(N'[dbo].[trg]')
               AND [type] = 'TR')
BEGIN
      DROP TRIGGER [dbo].[trg];
END;

Et pour simplifier, étant donné que le nom de l'objet doit être unique dans le schéma, il vous suffit de tester son existence. Si pour une raison quelconque, un type d'objet différent existe avec ce nom, le DROP TRIGGER échouera puisque cet autre objet est, eh bien, pas un déclencheur ;-). Par conséquent, j'utilise les éléments suivants:

IF (OBJECT_ID(N'[dbo].[trg]') IS NOT NULL)
BEGIN
      DROP TRIGGER [dbo].[trg];
END;
33
Solomon Rutzky

Si vous utilisez SQL Server 2016, vous pouvez utiliser une variante plus courte.

DROP TRIGGER IF EXISTS [dbo].[trg]

https://docs.Microsoft.com/en-us/sql/t-sql/statements/drop-trigger-transact-sql

4
Neshta

Peux-tu essayer

SELECT * FROM sys.objects WHERE [name] = PARSENAME('[dbo].[trg]',1) AND [type] = 'TR'

MODIFIER:

Eh bien, srutzky vous a déjà donné la réponse et bien expliqué, vous pouvez analyser le nom à l’aide de PARSENAME .

0
mxix