Vraag drop trigger if exists en create


Ik zou willen controleren of de trigger op [tbl] bestaat en een nieuwe aanmaken. Ik probeerde het op deze manier, maar werkte niet. Wat doe ik verkeerd?

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

12
2018-06-25 14:15


oorsprong


antwoorden:


De [name] veld in sys.objects bevat alleen de werkelijke naam (d.w.z. trg) niet inclusief het schema (d.w.z. dbo in dit geval) of enige tekstbepalende factoren (d.w.z. [ en ] in dit geval).

EN, u geeft de tabelnaam niet op voor DROP TRIGGER omdat de trigger een object op zichzelf is (in tegenstelling tot indexen). Dus je moet het verwijderen ON clausule (die alleen wordt gebruikt met DDL en Logon-triggers).

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

Houd er rekening mee dat u de letter van de objectnaam letterlijk moet voorafgaan met een N sinds de [name] veld is een sysname datatype dat gelijk is aan NVARCHAR(128).

Als u de schemanaam wel wilt opnemen, kunt u de OBJECT_ID() functie die schemanamen en tekstkwalificatoren toestaat (u zult dan moeten matchen object_id in plaats van name):

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

En om te vereenvoudigen, omdat de objectnaam uniek moet zijn binnen het schema, hoef je eigenlijk alleen maar te testen op zijn bestaan. Als om een ​​of andere reden een ander objecttype bestaat met die naam, dan is de DROP TRIGGER zal falen omdat dat andere object, nou ja, geen trigger is ;-). Daarom gebruik ik het volgende:

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

28
2018-06-25 14:20



Als u SQL Server 2016 gebruikt, kunt u een kortere variant gebruiken.

DROP TRIGGER IF EXISTS [dbo].[trg]

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


1
2017-08-28 10:25



Kun je het proberen

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

BEWERK:

Nou srutzky gaf je al het antwoord en werd goed uitgelegd, je kunt de naam ontleden met behulp van PARSENAME.


0
2018-06-25 14:20