Sql 字符串到datetime的转换失败,异常是如何找到导致它的行

Sql 字符串到datetime的转换失败,异常是如何找到导致它的行,sql,datetime,sql-server-2012,Sql,Datetime,Sql Server 2012,我目前正在将一些数据从一个非常旧的数据库(access 2.0)导入sql server 2012数据库。我将所有数据(包括日期字段,因为它的值为01.01.2005的01.01.105)导入到varchar字段中 然后我尝试将数据从临时表导入main表。 在那之前,一切都按预期进行,但一旦我开始导入数据 在maintable中(从表中),我在maintable中的datetime字段中遇到了一个错误 我总是在那里收到错误消息 SQL MyTestable中的字段是(Nr-int和datum-v

我目前正在将一些数据从一个非常旧的数据库(access 2.0)导入sql server 2012数据库。我将所有数据(包括日期字段,因为它的值为01.01.2005的01.01.105)导入到varchar字段中

然后我尝试将数据从临时表导入main表。 在那之前,一切都按预期进行,但一旦我开始导入数据 在maintable中(从表中),我在maintable中的datetime字段中遇到了一个错误

我总是在那里收到错误消息

SQL MyTestable中的字段是(Nr-int和datum-varchar(50))mymaintable中的字段(orderNo-int和orderDate-Datetime)

错误消息

Msg 6521,级别16,状态1,第1行发生.NET Framework错误 语句执行期间:System.Data.SqlTypes.SqlTypeException: SqlDateTime溢出。必须在1753年1月1日12:00:00 AM和 1999年12月31日晚上11:59:59。System.Data.SqlTypes.SqlTypeException:位于 System.Data.SqlTypes.SqlDateTime.FromTimeSpan(TimeSpan值)位于 位于的System.Data.SqlTypes.SqlDateTime.FromDateTime(日期时间值) System.Data.SqlServer.Internal.CXVariantBase.DateTimeToSSDate(DateTime dt)

附加信息

我只尝试了具有相同结果的select部分,但另一组数据(20k行中只有1k行)在没有引起错误的情况下运行

编辑: 我试图用另一篇文章中建议的使用datetime2而不是datetime来解决这个问题,而且这个方法很有效。但是,当我试图通过获取datetime2转换返回null的行来通过这种方式查找行时,我没有收到任何结果。这意味着本质上DAtetime转换失败,但datetime2转换根本不会失败

问题

从我所看到的(因为我已经成功地在数据的不同部分使用了它)来看,这似乎不是一个一般性错误,而是一个与数据相关的错误。 所以我的问题是:

有没有办法找出是哪一个确切的箭头导致了这些问题

(据我所知,try_parse在发生转换错误时应该返回null,而不是抛出异常)


感谢datetime2的功能,但datetime失败。我们必须考虑到datetime在日期方面比datetime2更具限制性。因此,通过修改SQL select,可以很容易地找到错误发生的位置:

 SELECT
    Nr,
    datum
FROM mytemptable
WHERE datum is not null and 
    TRY_PARSE(CASE WHEN len(datum) = 9
        THEN left(Datum,6) + CAST((CAST(right(Datum, 3) AS int) + 1900) AS varchar(4)) + ' 00:00:00.000'
        ELSE datum  + ' 00:00:00.000'
    END AS DATETIME2 USING 'de-DE') < '01.01.1753 00:00:00.000';
选择
Nr,
资料
来自我的诱惑
其中基准不为空且
尝试解析(len(datum)=9时的情况)
然后左(基准面,6)+转换(转换(右(基准面,3)为int)+1900)为varchar(4))+'00:00:00.000'
ELSE数据+00:00:00.000
使用“de”结束为DATETIME2<'01.01.1753 00:00:00.000';
添加了“基准不为空”部分,以确保只找到“未知”问题区域。 如果上面没有找到任何结果,则应使用datetime认为可以接受的最大日期(而不是最小日期)进行相同的操作


这样就可以很容易地找出转换失败的行。

快速浏览代码,我认为问题来自else语句。Else
Else数据+00:00:00.000'
。如果解析失败,这不应该是NULL吗。如果数据长度不是9个字符,则执行else语句。如果字符长度很长,这会不会创建一个超过9999年的最大日期值?这就是你的溢出将来自你应该能够为自己找到这些。您知道,已成功转换为
datetime2
。您知道它们不会转换为
datetime
datetime
具有更严格的工作年份范围,这些年份在错误消息中提到。因此,在转换为
datetime2
之后,搜索年份<1753的年份。啊,tnx忘了在那里提到。数据长度为9或10个字符(将在此处编辑帖子)。它要么是MM.DD.YYY(年份代表1990+YYY=实际年份),要么是10个字符长的MM.DD.YYY我已经将时间添加到了日期中,因为我一开始没有添加时间,但有转换错误。但总的来说,它只有这两个变体(使用len进行双重检查,只有这两个日期长度存在)@damien:tnx(只发现datetime2在创建这个问题后起作用
 SELECT
    Nr,
    datum
FROM mytemptable
WHERE datum is not null and 
    TRY_PARSE(CASE WHEN len(datum) = 9
        THEN left(Datum,6) + CAST((CAST(right(Datum, 3) AS int) + 1900) AS varchar(4)) + ' 00:00:00.000'
        ELSE datum  + ' 00:00:00.000'
    END AS DATETIME2 USING 'de-DE') < '01.01.1753 00:00:00.000';