确定触发变化的来源

时间:2018-07-12 18:49:10

标签: sql-server concurrency database-trigger audit-trail

我正在处理的应用程序具有审核功能,该功能可以通过在某些字段上设置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,因此任何代码都必须在所有这些代码中都能工作。

任何建议都将受到欢迎。

0 个答案:

没有答案