如何从临时表中编写动态SQL来更新每个员工记录?

时间:2016-03-10 16:51:44

标签: sql sql-server dynamic-sql

我有以下临时表(#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
;

显然,这不起作用,但即使经过几个小时的谷歌搜索和尝试,这是我能做的最好的。

任何人都可以帮助我并告诉我如何正确循环临时表吗?

3 个答案:

答案 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我认为