我已将一个简单的表添加到一个名为:aaa_log 的数据库中,其中包含列:( id
, name
, op
))
CREATE TABLE aaa_log (
[id] [int] IDENTITY(1,1) PRIMARY KEY NOT NULL,
[name] [varchar](50) NOT NULL,
[op] [varchar](50) NULL)
id
列用于保持顺序的方式。
我for insert, update, delete
使用以下脚本向数据库中的所有其他表添加了触发器 ():
declare @cmd varchar(max)
declare trigger_create cursor for
select 'Create trigger ['+TABLE_SCHEMA+'].[xxtr_'+TABLE_NAME+'_auto]
on ['+TABLE_SCHEMA+'].['+TABLE_NAME+'] fro insert,update,delete as
BEGIN
declare @op varchar(20)
if exists(SELECT * from inserted) and exists(SELECT * from deleted)
begin
set @op = ''update''
end
if exists(SELECT * from inserted) and not exists(SELECT * from deleted)
begin
set @op = ''insert''
end
if not exists(SELECT * from inserted) and exists(SELECT * from deleted)
begin
set @op = ''delete''
end
insert into aaa_log([name],[op]) values('+TABLE_SCHEMA+'.'+TABLE_NAME+', @op)
END
'
from information_schema.tables
where table_type='BASE TABLE' AND table_name <> 'aaa_log'
open trigger_create
fetch next from trigger_create into @sql
while @@FETCH_STATUS =0
BEGIN
exec(@sql)
fetch next from trigger_create into @sql
END
close trigger_create
deallocate trigger_create
没有其他人更新aaa_log
表,只有这些触发器,但是当我检查 aaa_log
表时,我看到一些op
为 NULL 的行。
我能想到的唯一选择是插入和更新都是空的,那么触发器是如何被激活的?
有什么解释吗?
您依赖于其中一个
inserted
或deleted
(或两者)中存在的行。当没有行受到影响时会发生什么?触发器仍然触发。为了避免这种事情,人们通常会以以下方式开始触发:
检查
@@ROWCOUNT
也很流行,但我发现它更脆弱。问题:如果不进行任何更改,您是否应该对数据库采取任何措施?这似乎会不必要地减慢您的应用程序,并且不是最佳实践。
我会说,如果可能的话,更好的解决方案是删除不必要的数据库事务。
如果此触发器旨在以任何方式进行审计(看起来确实如此),那么@Aaron Bertrand 的回答将不会记录审计表的任何更新。