【问题标题】:SQL Server : error conversion of a varchar data typeSQL Server:varchar 数据类型的错误转换
【发布时间】:2014-04-14 15:24:24
【问题描述】:

我正在尝试运行 SQL 查询,但出现错误

将 varchar 数据类型转换为 datetime 数据类型导致值超出范围。

代码:

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

任何建议将不胜感激

【问题讨论】:

  • 您的毫秒数可能有问题。另外,在您的查询中执行date = 并不是很有效。通常你会想做一个范围,比如午夜和午夜之间。
  • 嘿 Paqogomez 我已经尝试了 WHERE DatePassed Between '2011-04-28 00:00:00.000' and '2011-04-28 23:59:59.000' 我仍然收到错误
  • 毫秒呢?
  • 当你只做Between '2011-04-28 and '2011-04-29' 时会发生什么?默认情况下,这将为您提供 24 小时的范围。您可能还会遇到yyyy-mm-dd 的问题。请改用mm-dd-yyyy
  • Paqogomez 当我执行 between 语句时,我收到与以前相同的错误。我已经尝试过似乎可以工作的 dd-mm-yyyy 但是没有带回任何数据

标签: sql sql-server datetime


【解决方案1】:

从概念上讲,您认为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 标准格式的错误(但仅仅因为我认为这是一个错误并不一定能说服其他人)。

【讨论】:

  • 另外,不惜一切代价避免隐式转换。它可能无法解决您的问题,但将 DatePassed = '2011-04-28 00:00:00.000' 更改为 DatePassed = CAST('2011-04-28 00:00:00.000' AS DATETIME) 是一种很好的做法。
  • 嘿戈登这仍然给我错误The conversion of a varchar data type to a datetime data type resulted in an out-of-range value.
【解决方案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 中的日期格式设置,并且适用于所有情况!

或:

  • 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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多