每当在另一个名为"Candidate_Post_Info_Table_ChangeLogs"
的表中更新记录时,我都会尝试在名为"Candidate_Personal_Info_Table"
的表中插入数据。每当更新一条记录时我的代码工作正常,但当我尝试更新多行时,它会给出错误:
"子查询返回的值超过1"。
以下是我的代码:
ALTER TRIGGER [dbo].[Candidate_PostInfo_UPDATE]
ON [dbo].[Candidate_Post_Info_Table]
AFTER UPDATE
AS
BEGIN
IF @@ROWCOUNT = 0
RETURN
DECLARE @Candidate_Post_ID int
DECLARE @Candidate_ID varchar(50)
DECLARE @Action VARCHAR(50)
DECLARE @OldValue VARCHAR(MAX)
DECLARE @NewValue VARCHAR(MAX)
DECLARE @Admin_id int
IF UPDATE(Verified)
BEGIN
SET @Action = 'Changed Verification Status'
SET @Candidate_Post_ID = (Select ID From inserted)
SET @Candidate_ID = (Select Identity_Number from inserted)
SET @NewValue = (Select Verified From inserted)
SET @OldValue = (Select Verified From deleted)
IF(@NewValue != @OldValue)
BEGIN
INSERT INTO Candidate_Post_Info_Table_ChangeLogs(Candidate_Post_ID, Candidate_ID, Change_DateTime, action, NewValue, OldValue, Admin_ID)
VALUES(@Candidate_Post_ID, @Candidate_ID, GETDATE(), @Action, @NewValue, @OldValue, '1')
END
END
END
我已针对此问题搜索了堆栈溢出,但无法获得特定于此方案的任何相关答案。
答案 0 :(得分:1)
当您将多行插入/更新到表中时,系统使用的Inserted
临时表包含已插入或更新的所有行中的所有值。
因此,如果对6行进行更新,Inserted
表也将有6行,并执行以下操作:
SET @Candidate_Post_ID = (Select ID From inserted)
将返回错误,与执行此操作相同:
SET @Candidate_Post_ID = (SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6)
从事物的外观来看,你试图用迭代的方法做到这一点。基于集合更好。也许可以考虑在TRIGGER
的主体中这样做(没有所有参数......):
IF UPDATE(Verified)
BEGIN
INSERT INTO Candidate_Post_Info_Table_ChangeLogs
(
Candidate_Post_ID
,Candidate_ID
,Change_DateTime
,action
,NewValue
,OldValue
,Admin_ID
)
SELECT
I.ID
,I.Identity_Number
,GETDATE()
,'Changed Verification Status'
,I.Verified
,O.Verified
,'1'
FROM Inserted I
INNER JOIN Deleted O
ON I.ID = O.ID -- Check this condition to make sure it's a unique join per row
WHERE I.Verified <> O.Verified
END
答案 1 :(得分:0)
使用游标在以下主题中解决了类似案例....请检查
SQL Server A trigger to work on multiple row inserts
此外,以下主题提供了基于 set 的方法
的解决方案SQL Server - Rewrite trigger to avoid cursor based approach
*以上两个线程都来自堆栈溢出...