我有以下临时表(#updates
):
userid newvalue
------------------
031233 A
467763 B
656532 C
我需要为每个记录集更新用户表:
update tbl.users set foo = 'A' where id = '031233';
update tbl.users set foo = 'B' where id = '467763';
update tbl.users set foo = 'C' where id = '656532';
AFAIK,我需要动态SQL来读取#updates
表并执行更新:
declare @cnt int;
declare @id int = 1;
select @cnt = count(1) from #updates; -- 3
while @id <= @cnt
begin
select @id;
select @sql = N'update tbl.users set foo = ' + ?? + 'where id = ' + ??;
exec sp_executesql @sql;
select @id = @id + 1;
end
;
显然,这不起作用,但即使经过几个小时的谷歌搜索和尝试,这是我能做的最好的。
任何人都可以帮助我并告诉我如何正确循环临时表吗?
答案 0 :(得分:0)
你不需要循环。这可以使用join
完成。
update u
set foo = upd.newvalue
from tbl.users u
join #updates upd on u.id = upd.userid
答案 1 :(得分:0)
要遍历表格,您需要CURSOR
。您可以找到他们的文档here。在您的示例中,您的循环看起来像
Declare c CURSOR Local Fast_Forward For
Select userid, newvalue from #updates
Open c
Declare @userid varchar(10), @newvalue varchar(5)
Fetch Next From c Into @userid, @newvalue
While @@FETCH_STATUS = 0
Begin
select @sql = N'update tbl.users set foo = ' + @newvalue + 'where id = ' + @userid;
exec sp_executesql @sql;
Fetch Next From c Into @userid, @newvalue
End
Close c
Deallocate c
正如您所看到的,游标的设置非常冗长和丑陋。游标通常也不受欢迎,如果你真的需要,你应该只使用游标。在你的情况下,你不是。您可以将临时表连接到基表并以这种方式更新
Update u Set
foo = t.newvalue
From tbl.Users u
Join #updates t On t.userid = u.id
这更高效,更容易阅读
答案 2 :(得分:0)
不确定为什么要循环,查询就可以了。 由于没有人提出MERGE我做了:
MERGE INTO tbl.users
USING #updates
ON tbl.users.id = #updates.userid
WHEN MATCHED THEN
UPDATE
SET foo = #updates.newvalue
SQL服务器版本应该是&gt; = 2008我认为