2016-02-11 243 views
1

我正在寫使用語句INSERT INTO SELECT錯誤處理

INSERT INTO [tableName] 
..... 
SELECT * FROM [tableName] 

有時輸入表(SELECT)的存儲過程插入到表中的T-SQL可能包含錯誤值:表,其中插入是期望一個小數,並且select返回一個NVarChar值,這將引發轉換錯誤。 現在因爲語句執行了「批量插入」,我不知道插入的最後一條記錄是什麼或者包含錯誤數據的記錄是什麼。 SQL只說「轉換錯誤.....」 有什麼辦法可以「記錄」最後插入的記錄,以便至少我知道哪一行包含錯誤的值? (不使用遊標)

+0

你可以運行一個while循環,遍歷的ID,並通過一個由ID一個插入,每個插入之前打印的ID,所以你知道哪一個失敗 – artm

+0

什麼是您的源? – sagi

+0

如果批量失敗,沒有記錄被插入.. –

回答

2

沒有最後一個錯誤。

根據基本的數據庫ACID條件,該語句是ATOMIC - 它完全工作或完全失敗。還沒有內部處理行的定義順序 - 這可能會因服務器和數據特徵而異。

通常,在將數據複製到目標表之前會清理數據。

1

您可以嘗試使用OUTPUT子句,以便輸出插入的行直到遇到錯誤。您也可以使用ORDER BY,以便更快地確定哪個插入失敗的下一行。然後,知道失敗的行,應該更容易確定問題的領域。有一個OUTPUT子句

MSDN Link

的UPDATE,INSERT或DELETE語句將 回行即使語句遇到錯誤, 回滾客戶端。如果在運行語句時發生任何錯誤,則不應使用 。

5

觀察這個查詢的結果

SELECT 
    v.id, 
    v.val, 
    x=TRY_CAST(v.val AS DECIMAL(28,2)) 
FROM 
    (VALUES(1,'1.26'),(2,'A.13')) AS v(id,val) 
WHERE 
    TRY_CAST(v.val AS DECIMAL(28,2)) IS NULL 

結果:

+----+------+------+ 
| id | val | x | 
+----+------+------+ 
| 2 | A.13 | NULL | 
+----+------+------+ 

它採用TRY_CAST,返回NULL如果CAST失敗。您可以使用它來確定失敗的記錄,或者縮小您插入到目標表中的集合。

+0

好的技巧和嘗試的用法cast – TheGameiswar

1

您可以使用以下語句指出哪個列正在進行轉換問題。

SELECT SQL_VARIANT_PROPERTY(col1, 'BaseType') from Table1 

要過濾的問題

SELECT * from Table1 WHERE QL_VARIANT_PROPERTY(col1, 'BaseType') not like 'decimal%' 
+0

如果源列的類型是'NVARCHAR', 'SQL_VARIANT_PROPERTY(col,'BaseType')'只會返回'NVARCHAR'。這對OP沒有幫助。 –

+0

感謝您的信息:) –

1

我曾經面臨過這樣的問題,在一臺進口15萬行。我們最終決定它最好在SSIS中完成與以下方法:

  1. 創建可以說帶有一個後續其他「ON ERROR」只有
  2. 在第一數據任務設置n個數據的任務提交的批處理爲100K。並在錯誤轉到下一個我們命名爲10K
  3. 在這個任務,是10K,我們設置COMMIT批量爲10K和「ON錯誤」我們去1K等等等等。
  4. 我們最終在COMMIT BATCH數據任務「ON ERROR」的1條記錄中,將數據移動到一個具有足夠列(所有VARCHAR/NVARCHAR)的表中(調用ERROR RECORD表),以保存傳入數據+一個額外列爲該行保存SSIS錯誤消息。

當SSIS結束後,我們會分析所有失敗的記錄。通過這種方式,可以說你在1500萬個中只有5個錯誤記錄,我們可以在隔離表中成功插入1499995個記錄和5個記錄。

感謝,並希望這種方法能幫助