2010-06-08 30 views
7

我需要從一個表中獲取數據並將其導入到另一個表中。在僞代碼中,像這樣:T-SQL每個選擇?

For Each row in table1 
If row.personid is in table2 then 
    update table2.row 
Else 
    insert row into table2 
End If 
Next 

在T-SQL中執行此操作的最佳方法是什麼?據我所知,T-SQL不支持For Each..Next,那麼我有什麼替代方案?

+0

表1每個personid有一行還是可以有同一個人ID有多行? – Cervo 2010-06-23 20:46:22

回答

7

所有事情都是平等的,基於集合的操作更好。

update t1 
set t1.x = t2.x 
. 
. 
. 
from table1 t1 
inner join table2 t2 on t1.id = t2.t1id 

then 

insert into table1 
select * from table2 t2 where t2.t1id not in (select table1.id from table1) 
+1

@jvilalta你是說越大的數據集循環通過每條記錄的更多理由?我不得不不同意。 – Gratzy 2010-06-08 22:58:19

+0

不是說有更多的理由,只是在一個語句中進行插入和更新將這一切全部置於一個事務中,並且如果數據集足夠大,那麼轉換可能會失敗或者它會長時間運行,從而阻止其他事務精加工。 – jvilalta 2010-06-08 23:02:55

+0

@jvilalta我非常確定它不會運行太久或佔用儘可能多的資源循環播放每條記錄。 – Gratzy 2010-06-08 23:05:32

0

最常見的方法之一是使用遊標。這樣,您可以遍歷每個查詢返回的記錄並相應地處理它,或者使用UPDATE或INSERT。

請參見:http://msdn.microsoft.com/en-us/library/ms180169.aspx

+0

謝謝。我認爲這是一種選擇 - 但也讀到這是違反最佳做法的。b/c光標在內存管理等方面效果不佳。 – davemackey 2010-06-08 22:39:30

+2

@davemackey您閱讀正確。我不能相信有2人爲此推薦了遊標! – 2010-06-08 22:44:15

+1

不要拍馬丁使者。遊標是對給出的僞代碼的合理迴應,並且不知道更多信息,可能是一個完美的解決方案。這取決於它將如何使用,表格大小等。 – 2010-06-08 22:57:14

4

你可以使用光標這是其他人所描述。就我個人而言,我喜歡這樣做兩行:

UPDATE tbl2 SET field1=tbl1.field1, field2=tbl1.field2 -- etc. 
FROM tb12 
JOIN tbl1 on tbl2.personid = tbl1.personid 

INSERT tbl2 (personid, field1, field2) 
SELECT personid, field1, field2 
FROM tbl1 
WHERE NOT EXISTS (select personid from tbl2 where personid = tbl1.persondid) 
4

在while循環中這樣做是錯誤的。
對於你的狀態,你可以在sql server 2008中使用新的MERGE語句。
以下是關於如何操作的simple example

3

你說TSQL但不給版本。如果你在SQL2008上,Merge聲明應該做你需要的。

+0

謝謝,對不起,我們使用SQL 2008,但我們的某些數據庫正在SQL 2005/2000兼容模式下運行(第三方舊版軟件) – davemackey 2010-06-08 22:49:07

+0

它可能仍然有效。你試過了嗎?編輯:它說這裏支持SQL 2005兼容模式,但在2000年問題上保持沉默! http://msdn.microsoft.com/en-us/library/bb510680.aspx – 2010-06-08 22:51:22

4

如果您使用的是SQL Server 2008,那麼最好的方法是使用MERGE聲明。類似...

MERGE INTO target_table t 
USING source_table s 
ON t.personid = s.personid 
WHEN MATCHED THEN 
    UPDATE ... 
WHEN NOT MATCHED THEN 
    INSERT ... 
9

如果您使用的是SQL Server 2008,那麼您可以使用MERGE語句。也許這樣的事情:

MERGE table2 AS t -- target 
USING table1 AS s -- source 
    ON (t.personid = s.personid) 
WHEN MATCHED THEN 
    UPDATE 
    SET second_column = s.second_column, 
     third_column = s.third_column, 
     etc = s.etc 
WHEN NOT MATCHED THEN  
    INSERT (personid, second_column, third_column, etc) 
    VALUES (s.personid, s.second_column, s.third_column, s.etc)