2011-11-15 50 views
0

當更新一系列包含多個VarChar(n)列的表時,執行Replace操作的某些更新會使我的事務處理中「字符串或二進制數據將被截斷」。我試圖想出一個可重複的方法來處理這個問題。SQL Server字符串二進制數據將被截斷捕獲

一個選項是首先選擇行ID和要變換的列的長度,如果其長度超過列的大小。我不是這樣的粉絲,因爲它看起來像我不會得到任何查詢計劃重用,它會執行得很慢。

另一個選擇是弄清楚如何捕捉導致失敗的行(第一行?)並將其報告給調用者。我不認爲這會起作用,因爲錯誤級別太高,無法讓我指出問題所在。

我也可以通過獲取新值的子字符串/左側並放入它來忽略整個事情,但這會掩蓋它並且不讓我知道實際問題的位置。

我使用的是MSSQL 2008

編輯 - 這裏的想法看起來有點前途: http://sqlblogcasts.com/blogs/danny/archive/2008/01/12/scuffling-with-string-or-binary-data-would-be-truncated.aspx

1. Take a copy of the destination table: 
    SELECT * INTO #Destination FROM DestinationTable WHERE 1=2 
    GO 
    2. Set ANSI_WARNINGS OFF and perform the insert into the copy of the destination table, then set ANSI_WARNINGS ON again: 
    SET ANSI_WARNINGS OFF 
    GO 
    INSERT INTO #Destination 
    SELECT * FROM SourceTable 
    GO 
    SET ANSI_WARNINGS ON 
    GO 
    As ANSI_WARNINGS is off SQL Server truncates the fields rather than produces the warning. 
    3. Next compare what you would like to insert against what was inserted with the ANSI_WARNINGS OFF truncating. By using EXCEPT you only select the rows that don't match, and have therefore been truncated: 
    SELECT * FROM SourceTable 
    EXCEPT 
    SELECT * FROM #Destination 
    GO 

回答

1

,您在更新源是什麼?即你是否正在從另一個表中更新爲基於集的操作,或者從一個應用程序的循環中更新行?

這只是一個特定的列的問題,或者你遇到的各種列?

問題越有針對性越容易修復。回答,然後我會更新我的答案和更多信息。基本上,雖然你想查詢你的源數據只是不會導致問題和處理它們的記錄。然後將其餘的報告爲異常和/或截斷它們,以便它們可以被導入,如果這是你想要的。

編輯:我不知道你想要解決這個問題的是什麼樣的環境,但基本上你需要比較你輸入的數據長度和輸入的字段長度。如果你在純sql中這樣做,那很有可能做到這一點,但這將是一個巨大的痛苦。如果你使用.net或類似的語言,那麼它應該不會那麼麻煩。

您的檢查在更新之前完成,而不是作爲更新的一部分。因此重用查詢計劃不是問題。如果速度是一個問題,那麼你可能想要制定一個策略,只有在獲得了一定數量的更新提交後才進行更新。這樣,您可以一次對100個更新進行基於集合的操作,而不是每次1個。這假定你不需要實時更新。

+0

我正在從任意字符串更新。數據是要傳送到下游系統的報告輸出,有些數據需要追加,如追加文本末尾的「(已編輯)」。它有多個列,我已經堅持做動態SQL來首先創建更新語句。 – Snowy

+0

那麼每個字符串都包含多個記錄更新的數據,或者每個字符串只有一個記錄更新?還有一個問題:速度是一個問題?我假設你不是用像c#這樣的語言來做這件事,因爲這些例外很容易被捕獲。 –

+0

每個字符串更新一次。速度是一個問題,但完成工作也很重要。 – Snowy

1

「另一種辦法是找出如何捕捉到行(第一 行?)導致失敗,並報告給調用者。我不認爲這 會工作,因爲錯誤水平太高,讓我找出 的問題。「

我認爲你需要查明問題(即發生在哪一列)。如果不是這種情況,那麼你可以做以下事情:

你可以嘗試更新與ansi警告上,如果它導致錯誤,然後報告異常,關閉ansi警告並將其導入到表中,然後再次打開ansi警告。

但是,如果您確實需要查明問題,則需要更多代碼才能找到問題...但出於速度考慮,您可能不希望主動尋找錯誤,因此您只能使用上述技術一旦sql告訴你有一個問題,請查找該問題。

相關問題