如果存在则仅改变触发器

时间:2014-08-06 09:13:07

标签: sql sql-server triggers

我正在我的数据库上实施审核系统。它使用每个表上的触发器来记录更改。 我需要对这些触发器进行修改,因此我为每个触发器生成ALTER脚本。 我想做的只是在存在这些触发器时才会被改变,理想情况如下:

IF EXISTS (SELECT * FROM sysobjects WHERE type = 'TR' AND name = 'MyTable_Audit_Update')
BEGIN
ALTER TRIGGER [dbo].[MyTable_Audit_Update] ON [dbo].[MyTable]
 AFTER Update
...
END

然而,当我这样做时,我收到一条错误说"关键字TRIGGER附近的语法无效"

这些触发器可能不存在的原因是可以在最终用户可以指定的表上启用/禁用审计。这涉及创建或删除触发器。我无法在创建时对触发器进行更改,因为它们是动态创建的,因此我必须提供一种更改触发器的方法。

3 个答案:

答案 0 :(得分:5)

alter语句必须是批处理中的第一个。因此,对于sql server,它将是:

IF EXISTS (SELECT * FROM sysobjects WHERE type = 'TR' AND name = 'MyTable_Audit_Update')
BEGIN
EXEC('ALTER TRIGGER [dbo].[MyTable_Audit_Update] ON [dbo].[MyTable]
 AFTER Update
...')
END

答案 1 :(得分:1)

这可能与one that I found with Sybase years ago类似,我发现在尝试有条件地执行create table语句时,在评估条件语句之前执行DDL。唯一的解决方法是使用execute immediate

答案 2 :(得分:1)

CREATE TRIGGER不同,我找不到明确说明

的引用
  

CREATE TRIGGER必须是批处理中的第一个语句

但似乎此限制也适用于ALTER TABLE

执行此操作的简单方法是DROP TRIGGER并重新创建它:

IF EXISTS (SELECT * FROM sysobjects WHERE type = 'TR' AND name = 'MyTable_Audit_Update')
     DROP TRIGGER MyTable_Audit_Update 
GO

CREATE TRIGGER [dbo].[MyTable_Audit_Update] ON [dbo].[MyTable]
AFTER Update

...
END