如何将一个触发器写入 SQL Server 2008 的所有表
Posted
技术标签:
【中文标题】如何将一个触发器写入 SQL Server 2008 的所有表【英文标题】:How to write one trigger to all table to SQL Server 2008 【发布时间】:2013-11-16 10:47:31 【问题描述】:我写了一个触发器,当更新Employee
表时触发。
当触发器触发时,它将新记录插入Transact
表。
ALTER TRIGGER [PROJECTS].[after_updateEmployee] ON [PROJECTS].[Employee]
AFTER UPDATE
AS DECLARE @tablen varchar(30) , @modyfire varchar(15),@modyfied_date datetime,@columname varchar(20),@action varchar(6)
SET @tablen ='Employee'
set @modyfire =(SELECT SYSTEM_USER)
set @modyfied_date =(select CURRENT_TIMESTAMP)
SET @columname = (SELECT TOP 1 E_id FROM PROJECTS.Employee ORDER BY RV DESC)
set @action ='UPDATE'
BEGIN
INSERT INTO PROJECTS.Transact values(@tablen,@modyfire,@modyfied_date,@columname,@action)
END
我的数据库中有更多表。那么有什么方法可以为我的数据库中的所有表使用此触发器。
谢谢。
【问题讨论】:
触发器被定义在在一张桌子上——没有像全局触发器这样的概念。如果您想在 10 个表上触发,则必须编写 10 个触发器 - 每个表上一个。 如果你的触发器遵循一个模式——我假设你的模式是这样的——你应该能够通过在information_schema
上运行select
语句然后自动应用触发器来生成一个脚本(通过运行脚本)。
添加到以前的 cmets - 您可以通过创建 DDL 触发器为新创建的表自动化它,该触发器将向新表添加适当的触发器。
SQL Server 触发器有两个重要的警告信号。第一个是如果触发器假定只有一行被插入/更新/删除。第二个是如果触发器不包含对inserted
和/或deleted
伪表的任何引用。此触发器似乎同时存在这两个问题。
【参考方案1】:
根据this 的回答,您可以尝试以下方法:
创建一个包含对象id和表的新类型:
create type table_rows as table
(
row_id uniqueidentifier not null, -- deleted object id
table_name varchar(50) not null -- object's table
);
这个函数记录auto_log
表中每个被删除的对象:
create procedure mark_as_deleted(@r as table_rows readonly) as
begin
insert into auto_log (id, row_id, table_name, t_deleted, editor)
select NEWID(), row_id, table_name, getdate(), current_user from @r
end
最后是必须应用于每个表的触发器:
create trigger on_delete_object on [dbo].[object]
instead of delete as
begin
declare @table table_rows
insert into @table
select id, object_schema_name(parent_id) + '.' + object_name(parent_id)
from deleted
join sys.triggers on object_id = @@PROCID
-- Do what ever you need with deleted data
exec mark_as_deleted @table
end
这种方法的优点是所有触发器都很熟悉,并且用于处理已删除数据的代码放在单独的过程中
【讨论】:
以上是关于如何将一个触发器写入 SQL Server 2008 的所有表的主要内容,如果未能解决你的问题,请参考以下文章
将 .NET 类型映射到 SQL Server 200 数据类型