2012-05-30 29 views
0

我试图创建该表上component操作和记录UPDATEDELETEINSERT操作表component_historySQL服务器触发 - 设置变量= column.value

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); 

我怎么能发送触发来自表component的列(id, name, value)的信息转换为component_history

我已经试过:

SET 
@tr_id_component = component.id, 
@tr_name = component.name, 
@tr_value = component.value 

但报道:

消息4104,级别16,状态1,过程component_hist,第22行
多部分标识符“的组成部分。 ID“不能被绑定。

+0

这里给你的问题的一些元素在这里:http://stackoverflow.com/questions/1751715/sql-server-trigger-switching-insert-delete-update –

+2

假设至少有一个插入已成功处理(所以行存在于表中),'EXISTS(SELECT * FROM component)'将始终为真。触发器在每个语句中触发一次,而不是每行触发一次,因此考虑将值放入变量始终是错误的。 –

+0

这是第二件事,它是ORACLE的构造,但MSSQL不支持BEFORE语句,所以我现在只使用AFTER(我不知道如何解决之前):(( – gaffcz

回答

2

像这样的东西应该足够了:

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的顶部部分适用于insertupdate操作,因为我们使用的inserted表。但是我们检查deleted是否有任何行,以区分这两个操作。在底部的select(低于union all)中,我们查询deleted表 - 但我们使用where子句来防止任何行返回,如果这实际上是update操作。

+0

)作品!非常感谢:-) – gaffcz

+0

Damien,你能解释一下它是如何工作的吗?它可以工作,但我不知道如何... – gaffcz

+0

@gaffcz - 我已经添加了一些解释,猜测你想要插入和删除信息。如果不是,你能说出哪些位不清楚吗? –