SQL Server:varchar数据类型的错误转换

时间:2014-04-14 15:24:25

标签: sql sql-server datetime

我尝试运行SQL查询但是我收到了错误

  

将varchar数据类型转换为日期时间数据类型会导致超出范围的值。

代码:

SELECT 
    ClientId,
    DatePassed,
    Lender
FROM 
    dbo.tbl_Profile_Mortgage
WHERE 
    DatePassed = '2011-04-28 00:00:00.000'

我已将数据类型转换为

SELECT 
    ClientId,
    Convert (Date, DatePassed)
    Lender
FROM 
    dbo.tbl_Profile_Mortgage
WHERE 
    DatePassed = '2011-04-28 00:00:00.000'

然而,这仍然给我同样的错误

DatePassed的类型为datetime null

任何建议都将不胜感激

2 个答案:

答案 0 :(得分:3)

从概念上讲,您认为where子句是在convert()之前执行的。但这不一定是查询的运行方式。保证执行顺序的唯一SQL语句是case(然后不是所有时间)。

你可以试试这个:

SELECT ClientId,
       (case when isdate(DatePassed) = 1 then Convert (Date, DatePassed) end),
       Lender
FROM dbo.tbl_Profile_Mortgage
WHERE DatePassed = '2011-04-28 00:00:00.000';

编辑:

鉴于DatePassed已经采用日期时间格式,那么您的错误非常不寻常。这不是转换此列的问题,因为不涉及varchar

我唯一能想到的就是常数。也许你有一个奇怪的默认日期设置,它试图获得第28个月的第4天。如果是这样,您可以通过使用以下格式进行显式转换来轻松解决此问题:

SELECT ClientId,
       Convert(Date, DatePassed),
       Lender
FROM dbo.tbl_Profile_Mortgage
WHERE DatePassed = convert(date, '2011-04-28 00:00:00.000', 121);

Aaron Bertrand在他的blog中对这个问题进行了相当广泛的讨论。顺便说一下,即使我认识到他用YYYY-MM-DD格式提到的问题,我仍然默认使用它。我认为这是一个微软选择不识别这种ISO标准格式的错误(但仅仅因为我认为这是一个错误并不一定说服其他人)。

答案 1 :(得分:2)

SQL Server支持多种格式 - 请参阅MSDN Books Online on CAST and CONVERT。大多数格式都是依赖你所拥有的设置 - 因此,这些设置可能会有效 - 有时也不会。我想在你的情况下,你正在使用一种语言设置,这种设置很简单,不能使用你正在使用的字符串文字。

解决此问题的方法是使用SQL Server支持的(略微调整的) ISO-8601日期格式 - 此格式始终 - 无论您的是什么SQL Server语言和日期格式设置。

SQL Server支持ISO-8601 format有两种形式:

  • YYYYMMDD仅适用于日期(无时间部分);请注意:没有破折号!,这非常重要! YYYY-MM-DD 独立于SQL Server中的dateformat设置, NOT 可以在所有情况下使用!

或:

  • YYYY-MM-DDTHH:MM:SS了解日期和时间 - 请注意:此格式破折号(但可以可以省略),还有一个固定的T作为DATETIME的日期和时间部分之间的分隔符。

这适用于SQL Server 2000及更高版本。

如果您使用SQL Server 2008或更高版本以及DATE数据类型(仅DATE - DATETIME!),那么您确实也可以使用YYYY-MM-DD格式,也适用于SQL Server中的任何设置。

不要问我为什么整个主题都是如此棘手而且有点令人困惑 - 这就是它的方式。但是使用YYYYMMDD格式,您可以适用于任何版本的SQL Server以及SQL Server中的任何语言和日期格式设置。

对于SQL Server 2008及更高版本的建议是,如果您只需要日期部分,则使用DATE,当需要日期和时间时,使用DATETIME2(n)。您应尝试尽可能开始逐步淘汰DATETIME数据类型。

在具体案例中 - 在WHERE子句中使用此字符串:

WHERE DatePassed = '2011-04-28T00:00:00.000';

注意日期和时间部分之间的文字T