【问题标题】:Cant get the column name that is updated in a historical table in sql无法获取sql历史表中更新的列名
【发布时间】:2020-10-04 18:23:48
【问题描述】:

我在 sql server 中有一个表,其中有很多列,每次都可以更新。现在我想要一个插入到历史表中的触发器,我已经创建了在主表中更新的值。历史表是这样的:VarName(存储主表中更新的列名,ID(主表中行的id),OldValue(更新的旧值,NewValue(新的)值),日期(更新日期)。我使用此代码,但我希望触发器自动检测已更改的列并将其名称存储在 VarName 列中。请记住,在主表的一行中可以更新多个字段因此,如果更新了 3 个字段,则历史表将添加 3 行,其中包含主表中各自的列名及其旧值和新值的发生更新。 创建触发器 [dbo].UpdateOnMainTable ON [dbo].[MainTable] 更新后 作为 开始

    INSERT [dbo].[Historical] (VarName, ID, OldValue, NewValue, Date)
        SELECT ===> the code here
        FROM inserted i
        INNER JOIN deleted d
            ON i.ID = d.ID

结束 走 正如我解释的那样,我想要一个填充我的历史表的代码。

【问题讨论】:

    标签: sql sql-server-2012 triggers


    【解决方案1】:

    首先,您的结构要求数据类型与历史表中的列兼容。

    其次,您需要取消透视,然后从那里开始工作:

    with ic as (
          select i.id, v.*
          from inserted i cross apply
               (values ('col1', i.col1), ('col2', i.col2), ('col3', i.col3)
               ) v(col, val)
         ),
         dc as (
          select d.id, v.*
          from deleted d cross apply
               (values ('col1', d.col1), ('col2', idcol2), ('col3', d.col3)
               ) v(col, val)
         )
    insert into historical (varname, id, oldvalue, newvalue, date)
        select ic.col, ic.id, dc.val, ic.val, getdate
        from ic join
             dc
             on ic.id = dc.id and
                ic.col = dc.col and
                (ic.val <> dc.val or
                 ic.val is null and dc.val is not null or
                 ic.val is not null and dc.val is null
                );
    

    请注意,如果列具有不同的类型,则需要在 values() 语句中将它们强制转换(可能是字符串)。

    【讨论】:

    • @RediPrifti 。 . .将insert 放在同一个地方,大概是在update 触发器中。
    • 是的,我这样做了,但我尝试只更新一个值,它会影响 9 行我使用上面给出的代码。
    • @RediPrifti 。 . .我在几分钟前修复了代码。我错过了列名上的join 条件。
    • 是的,我正在寻找另一个加入,但你先添加了它。谢谢你帮了我很多:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-16
    • 2021-05-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多