2012-04-23 38 views
0

我見在T-SQL如下:T-SQL:INSERT INTO

INSERT INTO tblAttMain(Site, FirstName, LastName) 
    SELECT 
     Site, FirstName, LastName 
    FROM 
     tblAttTmp 
    WHERE 
     Site = @Site 

我在做什麼這裏從tblAttTmp複製列到tblAttMain表。請注意,select語句可以返回數百行。 tblAttTmp有一個稱爲ID的主鍵來指定該記錄的特定ID。

如果對於select的每次交互,如果出現錯誤,我喜歡吐出tblAttTmp的ID,並創建一個字符串,以便我可以看到需要修復的所有ID。

不知道該怎麼做,因爲選擇是一筆交易。

+0

你說什麼樣的錯誤? – 2012-04-23 20:44:27

回答

0

這聽起來像你寧願實施這個解決方案爲cursor。使用光標,你可以每次插入一個,而不是一堆,並在每次迭代過程中進行操作。

DECLARE @Cursor CURSOR FOR 
SELECT Site, FirstName, LastName FROM tblAttTmp WHERE Site = @Site 

DECLARE @CurrentSite <DataType> 
DECLARE @CurrentFirstName <DataType> 
DECLARE @CurrentLastName <DataType> 

OPEN @Cursor 

FETCH NEXT FROM @Cursor INTO @CurrentSite, @CurrentFirstName, @CurrentLastName 

WHILE @@FETCH_STATUS = 0 
BEGIN 
    -- INSERT using @CurrentSite, @CurrentFirstName, @CurrentLastName 
    -- Use a Try/ Catch block to catch errors 

    FETCH NEXT FROM @Cursor INTO @CurrentSite, @CurrentFirstName, @CurrentLastName 
END 

CLOSE @Cursor 
DEALLOCATE @Cursor 
+0

內存表會更簡單一些,可能會表現更好,但這確實有效。或者,甚至更好的是,在嘗試修改數據之前,OP可以主動檢查數據是否有錯誤。 – 2012-04-23 20:29:53

+0

非常真實。製作遊標可能非常容易出錯,只需要編寫多少代碼就可以實現一個簡單的概念,但是我認爲這是不考慮基於集合的操作的懲罰。 – Tejs 2012-04-23 20:38:38

+0

...然而,接受! – 2012-04-23 23:52:53

4

正如你所說,selectinsert是「一杆」。你有兩個真正的選擇:

  1. 單獨做每一行。 這不僅是壞,它也是一種痛苦
  2. 確定要插入之前可能發生什麼「錯誤」(初級/獨特/外鍵衝突,其他違反約束等)和校驗錯誤數據。

(你真的真的需要使用第二個選項)。

+0

無論如何sql中有嘗試並插入後獲取每個記錄的錯誤信息? – 2012-04-23 20:29:51

+1

@NatePet:SQL在遇到錯誤時將停止(並回滾)插入。您會看到它嘗試插入的第一個失敗記錄的錯誤信息;任何後續行都會出現的錯誤將不會顯示,因爲它們不會被嘗試。 – 2012-04-23 20:30:58