SQLBulkCopy和日期(1/1/1753)

时间:2011-11-18 16:49:52

标签: sql-server datetime ado.net sqlbulkcopy

我有一个应用程序已经工作了很长一段时间,但有一个恼人的项目,有时继续妨碍。

假设我使用OracleDataReader或MySQLDataReader之类的对象将数据传递给sqlbulkcopy对象进行插入。让我们假设所有列都映射得很好,而且大多数情况下,这一切都运行良好。

当然,我无法控制源应用程序或数据库(MySQL或Oracle)。因此,一些傻瓜会进入另一个应用程序,并在5/31/0210的发票表上输入日期。他真的打算放入2010年5月31日,但他使用的应用程序并没有非常严格地验证数据,Oracle数据库也接受了它。对于所有密集目的,5/31/0210的数据是Oracle db的有效日期。在数据输入方面可能是愚蠢的,但它就是现在的情况。

现在我们的OracleDataReader出现并通过SQLBulkCopy将此发票表传输到SQL Server。它将数据传递给具有正确列名和数据类型的完美匹配表。你可以看到会发生什么。 SQL Server数据库引擎不接受Oracle发布日期为05/31/0210的日期,因为DATETIME字段仅允许日期为1/1/1753至12/31/9999。

遇到此记录时,它只会失败并发出溢出错误。它不会跳过记录,它会杀死Feed。因此,如果它在一百万个记录表中发生了一千条记录,则不会获得剩余的999,000条记录。

有没有解决这个问题,以便饲料继续?

理想情况下,我想将接收SQL Server数据库移至2008并使用DATETIME2,这将允许这些愚蠢的日期,但遗憾的是并非我的所有客户都准备好转移到这个版本,所以我卡住了SQL 2000/2005/2008中使用DATETIME。

有关如何在不更改SQL的情况下解决此问题的任何想法?理想情况下,我不介意它是否只是跳过了记录。我知道我可以在SQL中为datareder执行此操作,但如果在单个查询中有20个日期字段,则会非常复杂。这将是维护噩梦。

任何想法都将不胜感激。

1 个答案:

答案 0 :(得分:0)

一种选择是将datetime列类型更改为varchar。然后添加派生列以将字符串转换为datetime。诀窍是使用派生列中的函数来验证日期,并在转换失败时放置任意日期时间。如果进行重日期比较,请保留计算列和/或将其编入索引。

我说的所有这一切都是因为sqlbulkcopy无法进行转换。也许你可以。希望有人会以某种方式参与其中。

SSIS在这种情况下会非常棒,因为您可以进行转换并获得批量更新锁的性能优势。