我正在尝试创建一个触发器,该触发器在表component
上运行,并将UPDATE
、DELETE
和INSERT
操作记录到表component_history
CREATE TRIGGER component_hist
ON component
AFTER INSERT, UPDATE, DELETE
AS
DECLARE
@tr_action varchar(8),
@tr_id_compoment int,
@tr_name varchar(max),
@tr_value int
IF COLUMNS_UPDATED() <> 0 -- delete or update?
BEGIN
SET @tr_action = 'UPDATE'
ELSE -- delete
BEGIN
SET @tr_action = 'DELETE'
END
INSERT INTO component_history VALUES (@tr_id_component, @tr_name, @tr_value, @tr_action);
如何将列(id, name, value
)的信息从表component
发送到component_history
我试过:
SET
@tr_id_component = component.id,
@tr_name = component.name,
@tr_value = component.value
但它报告说:
Msg 4104,16级,状态1,过程component_hist,第22行
多部分标识符"component.id“无法绑定.
发布于 2012-05-29 23:21:18
这样的东西就够了:
CREATE TRIGGER component_hist
ON component
AFTER INSERT, UPDATE, DELETE
AS
INSERT INTO component_history /* I'd prefer to see a column list here */
select id,name,value,CASE WHEN EXISTS(select * from deleted) THEN 'UPDATE' ELSE 'INSERT' END
from inserted
UNION ALL
select id,name,value,'DELETE'
from deleted
where not exists(select * from inserted)
一个小的优化(如果您有大量的大型更新)将是将EXISTS (select * from deleted)
评估移出SELECT
(因为它目前将每一行评估一次)。
还要注意,在UPDATE
的情况下,我们只是存储新值,而不是旧值。
inserted
and deleted
pseudo-tables是特殊的--它们包含受导致触发器触发的语句影响的行。inserted
表包含任何新行,deleted
表包含任何旧行。这导致了这样的逻辑:在insert
期间,deleted
将是空的(没有旧行受到插入的影响)。在delete
期间,inserted
将为空(未创建新行)。在update
期间,两个表都被填充。
这就是为什么select
的顶部同时适用于insert
和update
操作的原因,因为我们使用的是inserted
表。但是我们检查deleted
中是否有行,以区分这两个操作。在底部的select
中(在union all
下面),我们查询deleted
表,但是如果这实际上是一个update
操作,则使用where
子句来防止返回任何行。
https://stackoverflow.com/questions/10811491
复制