2011-11-18 82 views
0

我有一個應用程序已經運行良好很長一段時間,但有一個煩人的項目,有時繼續阻礙。SQLBulkCopy和日期(1/1/1753)

假設我使用諸如OracleDataReader或MySQLDataReader之類的對象將數據傳遞給sqlbulkcopy對象進行插入。我們假設所有的列都很好,大部分都能正常工作。

當然,我無法控制源應用程序或數據庫(即MySQL或Oracle)。因此,一些混亂進入不同的應用程序,並在2002年5月31日的發票表中加入日期。他真的打算在5/31/2010投入使用,但是他使用的應用程序不能非常嚴格地驗證數據,Oracle數據庫也會接受它。對於所有密集的目的,5/31/0210的數據是Oracle數據庫的有效日期。它可能在數據輸入方面很愚蠢,但現在就是這樣。

現在我們的OracleDataReader出現了,並通過SQLBulkCopy將此發票錶轉移到SQL Server。它將數據傳遞給具有正確列名和數據類型的完美匹配表。你可以看到會發生什麼。 Oracle的05/31/0210日期不被SQL Server數據庫引擎接受,因爲DATETIME字段只允許日期從1/1/1753到12/31/9999。

當它遇到這條記錄時,它只會失敗並且會發生溢出錯誤。它不會跳過記錄,它會殺死Feed。因此,如果它發生在一百萬張記錄表上的一千條記錄中,則不會獲得剩餘的999,000條記錄。

無論如何避免這個問題,以便飼料將繼續?

理想情況下,我想將接收SQL Server數據庫移動到2008年,並使用DATETIME2,這將允許這些愚蠢的日期,但不幸的是,並非所有的客戶端都準備好移動到此版本,所以我DATETIME在SQL 2000/2005/2008中停滯不前。

有關如何在不更改SQL的情況下解決此問題的任何想法?理想情況下,我不介意它是否跳過記錄。我知道我可以在datareder的SQL中執行此操作,但是如果在單個查詢中有20個日期字段,這將非常複雜。這將是維修的噩夢。

任何想法將不勝感激。

回答

0

一個選項是將datetime列類型更改爲varchar。然後添加一個將字符串轉換爲datetime的派生列。訣竅是使用派生列中的函數來驗證日期,並在覆蓋失敗時放置任意日期時間。如果您進行繁重的日期比較,請堅持計算的列和/或索引它。

我說這一切都是因爲sqlbulkcopy無法做到轉換。也許你可以。希望有人會以某種方式加入。

SSIS在這種情況下會很棒,因爲您可以進行轉換並獲得批量更新鎖的性能優勢。