2016-03-10 45 views
-1

我有以下臨時表(#updates):如何從臨時表編寫動態SQL以更新每個員工記錄?

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

你不需要循環。這可以通過join完成。

update u 
set foo = upd.newvalue 
from tbl.users u 
join #updates upd on u.id = upd.userid 
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 

這是更高性能,更易於閱讀

0

不知道爲什麼要循環,查詢是好的。 既然沒有人提出了一個MERGE我做的:

MERGE INTO tbl.users 
    USING #updates 
     ON tbl.users.id = #updates.userid 
WHEN MATCHED THEN 
    UPDATE 
     SET foo = #updates.newvalue 

SQL Server版本應該是> = 2008年,我認爲

相關問題