drop exists如果存在并创建

use*_*326 19 sql t-sql sql-server triggers sql-server-2008

我想检查[tbl]上是否存在触发器并创建另一个触发器.我试过这种方式,但没有奏效.我究竟做错了什么?

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
Run Code Online (Sandbox Code Playgroud)

Sol*_*zky 42

[name]现场sys.objects将只包含实际名称(即trg),包括架构(即dbo在这种情况下)或者任何文本识别符(即[]在这种情况下).

AND,您没有指定表名,DROP TRIGGER因为触发器本身就是一个对象(与索引不同).因此,您需要删除该ON子句(仅用于DDL和Logon触发器).

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

请注意,您应该在对象名称字符串文字的前面添加一个,N因为该[name]字段是sysname等于的数据类型NVARCHAR(128).

如果您确实想要合并模式名称,则可以使用OBJECT_ID()允许模式名称和文本限定符的函数(然后需要匹配object_id而不是name):

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

为了简化,由于对象名称在模式中需要是唯一的,因此您只需要测试它的存在.如果由于某种原因存在具有该名称的不同对象类型,DROP TRIGGER则将失败,因为其他对象是,而不是触发器;-).因此,我使用以下内容:

IF (OBJECT_ID(N'[dbo].[trg]') IS NOT NULL)
BEGIN
      DROP TRIGGER [dbo].[trg];
END;
Run Code Online (Sandbox Code Playgroud)


Nes*_*hta 5

如果使用SQL Server 2016,则可以使用较短的变体。

DROP TRIGGER IF EXISTS [dbo].[trg]
Run Code Online (Sandbox Code Playgroud)

https://docs.microsoft.com/zh-cn/sql/t-sql/statements/drop-trigger-transact-sql