drop exists如果存在并创建

时间:2015-06-25 14:15:41

标签: sql sql-server sql-server-2008 tsql triggers

我想检查[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

3 个答案:

答案 0 :(得分:35)

[name]中的sys.objects字段仅包含实际名称(即trg),,包括架构(即dbo in这种情况)或任何文本限定符(在这种情况下为[])。

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;

请注意,您应该在对象名称字符串文字前加N作为前缀,因为[name]字段是等于sysname的{​​{1}}数据类型。

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

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;

答案 1 :(得分:4)

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

DROP TRIGGER IF EXISTS [dbo].[trg]

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

答案 2 :(得分:0)

你能试试吗

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

编辑:

srutzky已经给了你答案并且解释得很清楚,你可以在PARSENAME的帮助下解析这个名字。