我有以下触发器:
CREATE TRIGGER trFoodUpdate ON Food
AFTER UPDATE
AS
DECLARE @Action nvarchar(1000) = 'Change(s): '
IF Inserted.FoodID <> Deleted.FoodID THEN SET @Action += CHAR(13) + '-You have updated FoodID from ' + Inserted.FoodID + 'to ' + Deleted.FoodID
.... --Other IF-s--
INSERT INTO FoodTriggerTable (FoodID, FoodName, FoodDesc, FoodPrice, Action, InsertActionTime)
SELECT FoodID, FoodName, FoodDesc, FoodPrice, @Action, GETDATE() FROM Inserted
GO
我正在尝试将更新的FoodID
,FoodName
等插入我的FoodTriggerTable
。但是,我似乎做不到:
IF Inserted.FoodID <> Deleted.FoodID THEN ...
它说“无法绑定多部分标识符” Inserted.FoodID”。 Deleted.FoodID
上发生相同的错误。为什么会这样?
我认为我可以使用DECLARE
声明临时变量,该临时变量可以存储上述表中的所有所需数据,但是我可以使用上面的方法吗?
编辑
我似乎误解了SQL Server中的许多概念,但是我试图将更新后的FoodID
,FoodName
和其余字段插入到名为FoodTriggerTable
的表中,其中存储了“日志”,其中包含有关记录更新的信息。
我正在尝试插入一个句子,该句子列出Food
内FoodTriggerTable
表中对记录所做的更改。因此,我尝试设置一个名为@Action
的新变量来存储一个字符串,然后将其与其他字符串连接。 @Action
包含的字符串然后将使用以下命令插入到Action
的{{1}}字段中:
FoodTriggerTable
假设我只更新了INSERT INTO FoodTriggerTable (FoodID, FoodName, FoodDesc, FoodPrice, Action, InsertActionTime)
SELECT FoodID, FoodName, FoodDesc, FoodPrice, @Action, GETDATE() FROM Inserted
表中的食物价格,我希望Food
中的Action
字段包含以下字符串:
FoodTriggerTable
所以我要尝试的是连接Change(s): You've changed the food price from 30 to 45
。
答案 0 :(得分:2)
Sean的评论已经指出了您的代码所证明的基本误解。
从技术和具体角度来说,出现The multi-part identifier "Inserted.FoodID" could not be bound
错误的原因是因为您没有在FROM子句中包含Inserted
或Deleted
。
不可能从损坏的代码中获得100%的确定,但是可能需要做的是使用CASE表达式在代码的最终INSERT查询中计算Action
列,以便每一行单独处理。
答案 1 :(得分:2)
这是解决此类问题的一种方法的完整示例。它跟踪所有列中的更改。除了示例触发器之外,我还创建了Food和FoodAudit表。然后,我创建了一些数据并对其进行了几次更新,以便您了解其工作原理。
create table Food
(
FoodID int identity
, FoodName varchar(100) not null
, FoodDesc varchar(100) not null
, FoodPrice decimal(7,2) not null
)
create table FoodAudit
(
FoodID int not null
, FoodName varchar(100) not null
, FoodDesc varchar(100) not null
, FoodPrice decimal(7,2) not null
, ChangeDate datetime not null
CONSTRAINT DF_FoodAudit_ChangeDate DEFAULT getdate()
)
GO
create trigger TR_Food on Food after UPDATE as
set nocount on;
insert FoodAudit
(
FoodID
, FoodName
, FoodDesc
, FoodPrice
, ChangeDate
)
select d.FoodID
, d.FoodName
, d.FoodDesc
, d.FoodPrice
, getdate()
from deleted d
GO
insert Food
(
FoodName
, FoodDesc
, FoodPrice
)
select 'Bacon'
, 'Yummy'
, 3.42
GO
update Food
set FoodPrice = 1.23
where FoodName = 'Bacon'
waitfor delay '00:00:02' --used to simulate updates at different times.
update Food
set FoodPrice = 12.23
, FoodDesc = 'wow'
where FoodName = 'Bacon'
waitfor delay '00:00:02' --used to simulate updates at different times.
update Food
set FoodPrice = 12.23
, FoodDesc = 'wait'
where FoodName = 'Bacon'
waitfor delay '00:00:02' --used to simulate updates at different times.
update Food
set FoodDesc = 'Yummers'
where FoodName = 'Bacon'
waitfor delay '00:00:02' --used to simulate updates at different times.
select * from FoodAudit