首页 > 解决方案 > 确定要触发的变更来源

问题描述

我工作的应用程序有一个审计功能,它通过在某些字段上设置 SQL 触发器来工作。当检测到更改时,触发器将触发并向审计表添加一行,指示更改的字段、更改字段的更改类型(更新、插入或删除)键值以及前后值。但是,可以通过各种程序模块进行更改,我想跟踪哪个模块或子模块进行了特定更改。这是一个多用户并发应用程序,因此不同的用户(或脚本)可能同时运行不同的模块或同一模块的不同实例。锁定防止不同用户同时更改同一记录,并且工作正常。

这是一个更新表的现有触发器。插入和删除的触发器以及第二个表上的触发器都非常相似。(表名和字段名已更改)

ALTER trigger [dbo].[APP_trg_AU_Ptbl1]
on [dbo].[Ptbl1] for update as
declare @ct int, @now datetime, @id int

select @ct = @@rowcount
if @ct = 0 return

select @id = s.user_identity
  from SpidUser s inner join master..sysprocesses m
  on m.spid = s.spid and m.login_time = s.login_time
  where m.spid = @@SPID
select @id = isnull(@id, 0)
select @now = getdate()

insert AuditTbl(edit_time, edit_type, useridentity, table_name,
field_name, old_value, new_value, _fk_table, _fk_person, _fk_event)

select @now, convert(char(1),'U'), @id, 'Ptbl1',
convert(varchar(255), 'item_code'), convert(varchar(255),
deleted.item_code), convert(varchar(255), _src.item_code),
convert(int, _src._pk), convert(int, EVENT.person_id), convert(int,
EVENT.EVENT_id)
FROM deleted INNER JOIN inserted AS _src ON deleted._pk=_src._pk INNER JOIN
EVENT ON _src._fk_event=EVENT.EVENT_id
WHERE 1 = CASE
  WHEN _src.item_code is null THEN 
    CASE WHEN deleted.item_code is null THEN 0 ELSE 1 END
  ELSE CASE WHEN deleted.item_code is null THEN 1
    ELSE CASE WHEN _src.item_code = deleted.item_code THEN 0 ELSE 1 END
  END
END

UNION ALL select @now, convert(char(1),'U'), @id, 'Ptbl1',
'item_sequence_num', convert(varchar(255), deleted.item_sequence_num),
convert(varchar(255), _src.item_sequence_num), _src._pk, EVENT.person_id,
EVENT.EVENT_id
FROM deleted INNER JOIN inserted AS _src ON deleted._pk=_src._pk INNER JOIN
EVENT ON _src._fk_event=EVENT.EVENT_id
WHERE 1 = CASE
  WHEN _src.item_sequence_num is null THEN 
    CASE WHEN deleted.item_sequence_num is null THEN 0 ELSE 1 END
  ELSE CASE WHEN deleted.item_sequence_num is null THEN 1
    ELSE CASE WHEN _src.item_sequence_num = deleted.item_sequence_num THEN 0 ELSE 1 END
  END
END

我希望能够设置一个标识当前活动模块的字符串,以便触发器能够在将记录添加到审计表时将其拾取并包含它。我无法锁定每个人都会写入的表/字段组合,因为这会序列化所有数据库访问并破坏并发性,从而破坏性能。我不确定我可以在哪里放置或公开字符串,以便触发器可以可靠地将其与导致触发器触发的特定更改相关联。

客户端站点混合使用 SQL-server 2005、2008 和 2012,因此任何代码都必须在所有这些中工作。

欢迎大家提出意见。

标签: sql-serverconcurrencydatabase-triggeraudit-trail

解决方案


推荐阅读