【问题标题】:SQL Server trigger - SET variable = column.valueSQL Server 触发器 - SET 变量 = column.value
【发布时间】:2012-06-04 09:43:32
【问题描述】:

我正在尝试创建一个触发器,该触发器在表 component 上运行并将 UPDATEDELETEINSERT 操作记录到表 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);

如何将表 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 行
无法绑定多部分标识符“component.id”。

【问题讨论】:

  • 这里回答您问题的一些元素:stackoverflow.com/questions/1751715/…
  • 假设已经成功处理了至少一个插入(因此表中存在行),EXISTS (SELECT * FROM component) 将始终为真。并且触发器每条语句触发一次,而不是每行触发一次,因此考虑将值放入变量中总是错误的。
  • 这是第二件事,它是ORACLE的构造,但是MSSQL不支持BEFORE语句,所以我现在只使用AFTER(我不知道如何解决BEFORE): (((

标签: sql sql-server-2008


【解决方案1】:

这样就足够了:

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)

small 优化(如果您有很多 large 更新)将把 EXISTS (select * from deleted) 评估移出 SELECT(因为它目前是每行评估一次)。

另外请注意,在 UPDATE 的情况下,我们只是存储新值,而不是旧值。


inserted and deleted pseudo-tables 是特殊的 - 它们包含受导致触发器触发的语句影响的行。 inserted 表包含所有新行,deleted 表包含所有旧行。这导致在insert 期间deleted 将是空的逻辑(没有旧行受插入影响)。在delete 期间,inserted 将为空(未创建新行)。在update 期间,两个表都被填充。

这就是select 的顶部同时适用于insertupdate 操作的原因,因为我们使用的是inserted 表。但是我们检查deleted中是否有行,以区分这两个操作。在底部 selectunion all 下方)中,我们查询 deleted 表 - 但如果这实际上是 update 操作,我们使用 where 子句来防止返回任何行。

【讨论】:

  • Damien,你能解释一下它是如何工作的吗?它有效,但我不知道如何......
  • @gaffcz - 我已经添加了一些解释,猜你想知道inserteddeleted 的信息。如果没有,您能说一下您不清楚哪些地方吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-12-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-04-25
  • 2015-01-31
相关资源
最近更新 更多