【问题标题】:Only ALTER a TRIGGER if is exists如果存在,则仅 ALTER a TRIGGER
【发布时间】:2014-08-06 09:13:07
【问题描述】:

我正在我的数据库上实施一个审计系统。它使用每个表上的触发器来记录更改。 我需要对这些触发器进行修改,因此要为每个触发器生成 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 附近的语法无效”

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

【问题讨论】:

  • 尝试在BEGINALTER 行之间添加GO
  • 谢谢,但这给出了一个错误,说它找不到触发器。

标签: sql sql-server triggers


【解决方案1】:

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

【讨论】:

  • 顺便说一句,我会先写出触发器,测试它,然后用 EXEC 包装它,因为尝试在 EXEC() 中进行调试可能很困难
  • 谢谢,帮了大忙。
【解决方案2】:

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

【讨论】:

    【解决方案3】:

    CREATE TRIGGER 不同,我没有找到明确声明的参考

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

    但似乎这个限制也适用于ALTER TABLE

    执行此操作的简单方法是删除触发器并重新创建它:

    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
    

    【讨论】:

      猜你喜欢
      • 2018-03-27
      • 2016-10-28
      • 1970-01-01
      • 2013-10-25
      • 2019-01-13
      • 1970-01-01
      • 1970-01-01
      • 2015-05-01
      • 1970-01-01
      相关资源
      最近更新 更多