我尝试更新我的表时遇到以下错误,尽管没有任何子查询:
Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression.
我的查询:
UPDATE t1
SET t1.modified = 2
FROM TransActions AS t1
INNER JOIN Ruser R
ON t1.USERID = r.USERID
WHERE r.dep_code = 54 and r.dep_year =2014
and YEAR(t1.checktime) =2016 and MONTH(t1.checktime) =1 and t1.modified = 0
选择的数据如下:
USERID empNum
3090 25
3090 25
2074 464
根据评论我的更新触发器:
after update
as
declare @userid int , @date date
if (select userid from inserted)<>(select userid from deleted )
raiserror ('YOU ARE NOT ALLOWED TO PERFORME THIS ACTION',10 , 1)
ELSE
begin
set nocount on;
set @userid = (select userid from inserted)
set @date = (select convert(date , checktime) from inserted)
exec calc_atten @date , @userid
end
答案 0 :(得分:3)
触发器按语句执行,而不是按行执行,这是您的错误来源。 你的触发器假设插入和删除的表只有一行,但这是完全错误的 插入/删除表中的行数是受DML语句影响的行数(更新/插入/删除)。
我不知道程序calc_atten
的作用,但你需要找到一种方法来在设定的级别上执行它的逻辑,而不是现在的标量变量。< / p>
应该更改触发开始时的条件以适应多行更新。 一种方法是:(如果我知道表的结构,我可能会写得更短更好)
IF EXISTS (
SELECT 1
FROM deleted d
INNER JOIN inserted i
ON d.[unique row identifier] = i.[unique row identifier]
WHERE i.userId <> d.UserId
)
* [唯一行标识符]表示该表中每行唯一的列或列组合。如果唯一行标识符包含UserId列,那么这将无法正常工作。
答案 1 :(得分:2)
您的查询没问题。问题是触发器。 inserted
和deleted
是表格(嗯,实际上是视图但不相关),因此它们可以包含多行。
假设transactions
有主键,您可以通过执行
declare @userid int , @date date ;
if (exists (select 1
from inserted i
where not exists (select 1
from deleted d
where d.transactionid = i.transactionid and
d.userid <> i.userid
)
)
)
begin
raiserror ('Changing user ids is not permitted', 10 , 1);
end;
else begin
set nocount on;
declare icursor cursor for select userid, checktime from inserted;
open icursor;
fetch next from icursor into @userid, @date;
while not @@FETCH_STATUS = 0
begin
exec calc_atten @date, @userid
fetch next from icursor into @userid, @date;
end;
close icursor; deallocate icursor;
end;
游标不是我最喜欢的SQL构造。但是,如果您需要遍历表并调用存储过程,那么它们是合适的。如果你可以重写基于集合的代码,那么你可以摆脱光标。
答案 2 :(得分:0)
尝试使用不同的方式:
UPDATE t1
SET t1.modified = 2
FROM TransActions AS t1
INNER JOIN (select distinct userid from Ruser
where r.dep_code = 54 and r.dep_year = 2014 ) R
ON t1.USERID = r.USERID
WHERE YEAR(t1.checktime) =2016 and MONTH(t1.checktime) =1 and t1.modified = 0
顺便说一句 - 我在这里看不到任何子查询,所以很奇怪你得到的错误,我感觉错误不会因为代码的那部分而发生。
答案 3 :(得分:0)
您可以使用distinct返回唯一的用户ID:
UPDATE TransActions
SET modified = 2
WHERE YEAR(checktime) = 2016
AND MONTH(checktime = 1
AND modified = 0
AND userid IN ( SELECT DISTINCT userid FROM Ruser r WHERE r.dep_code = 54 and r.dep_year =2014 );