【问题标题】:SQL Server trigger - copy row before updatingSQL Server 触发器 - 更新前复制行
【发布时间】:2009-07-27 11:42:53
【问题描述】:

我想在更新之前复制一个表的行,我正在尝试这样做:

CREATE TRIGGER first_trigger_test
on Triggertest
FOR UPDATE
AS
insert into Triggertest select * from Inserted

很遗憾,我收到了错误消息

Msg 8101, Level 16, State 1, Procedure first_trigger_test, Line 6
An explicit value for the identity column in table 'Triggertest' can only be specified when a column list is used and IDENTITY_INSERT is ON.

我认为这是因为 id 列;我不能做类似'除了'id之类的事情吗?我不想列出触发器中的所有列,因为它应该尽可能动态...

【问题讨论】:

  • 请使用标签“sql-server”而不是“mssql”。
  • 没有。错误信息是正确的。

标签: sql-server triggers


【解决方案1】:

你不能,基本上。您要么必须指定列,要么使用单独的表:

CREATE TRIGGER first_trigger_test
on Triggertest
FOR UPDATE
AS
insert into Triggertest_audit select * from deleted

(其中Triggertest_audit 是第二个表,看起来像Triggertest,但没有主键/身份/等 - 通常每个逻辑源行多行;我不认为您真的想复制 old 值,而不是新值)

【讨论】:

    【解决方案2】:

    出现问题是因为您尝试在 Triggertest 中设置标识列。 这是你的计划吗?

    1. 如果要将新的标识列从 INSERTED 复制到 Triggertest 中,则在 Triggertest 中定义该列而不使用 IDENTITY

    2. 如果 Triggertest 有自己的 IDENTITY 列,请使用:

      insert into Triggertest (col1, col2, col3) select col1, col2, col3 from Inserted

    评论后:

    不,你不能没有动态 SQL 来检测什么表并找到所有非标识列。

    但是,如果您添加或删除列,您将在触发器表和 Triggertest 之间出现不匹配的情况,并且您会得到不同的错误。

    如果您真的希望它具有动态性,则必须将所有列合并为一个或使用 XML 来忽略架构。

    最后:

    您的所有表是否都具有与 TriggerTest 完全相同的列数、数据类型和可空性...因为这是这里的假设...

    【讨论】:

    • 感谢您的回答,但正是这两件事是我的问题: - 我不想明确列出所有列(因为我想在不同的表上使用相同的触发器,它应该如果稍后添加或删除列,则为动态)-不应复制标识列,因此类似于“复制除标识列之外的行”
    【解决方案3】:

    如果您希望每次触发器运行时都构建表,那么您别无选择,只能使用系统表来查找列并使用这些列定义创建表。当然,您的第一步必须是删除现有表,否则触发器将在有人第二次更新记录时不起作用。

    但是,我认为您需要重新考虑这个过程。每次更改记录时删除一个表然后创建一个新表是一个非常糟糕的主意。当这张表可能每秒钟左右被清除和重建时,它有什么用处?

    您可能会考虑创建一个动态过程来创建创建触发器脚本,该脚本具有该表的正确信息但不是动态的。然后,您的配置人员需要在每次表更改时运行此过程。

    请记住,触发器做两件事是至关重要的,即尽可能快地运行,并负责处理批处理中的所有记录(触发器永远不应该有逐行处理或其他缓慢的过程,或者假设只有一行会在插入或删除的表中)触发器中的动态 SQL 也可能是一个坏主意,因为您无法事先测试所有可能性,并且当发生一些意想不到的事情时,可能会使您的整个生产服务器停止运行。

    【讨论】:

      猜你喜欢
      • 2016-11-03
      • 1970-01-01
      • 2011-06-03
      • 1970-01-01
      • 1970-01-01
      • 2017-10-23
      • 2014-03-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多