【问题标题】:Why does SQL Server return 0 for ISDATE('13/01/2010')为什么 SQL Server 为 ISDATE('13/01/2010') 返回 0
【发布时间】:2012-07-11 12:24:00
【问题描述】:

我有一个视图,其中有一列在 varchar formet 和 dd/MM/yyyy 中有日期 当我尝试使用 order by 它给出的错误是

Msg 241, Level 16, State 1, Line 2 转换时转换失败 字符串中的日期和/或时间。

查询是

select * from test1.dbo.abcd order by CONVERT(date,ddate,103)

它返回 0 的某些日期是 13/01/2010

18/12/2009
20/10/2009
21/06/2010
19/10/2009
18/11/2010
29/10/2009
29/10/2009
18/03/2010
15/03/2010
15/03/2010
15/03/2010
15/04/2010
15/04/2010
15/04/2010
15/04/2010
30/03/2010
14/05/2010
14/01/2010
23/10/2009
20/10/2009
27/10/2009
27/10/2009
20/07/2009
20/04/2010
13/08/2010
30/06/2011
23/07/2010
27/08/2010
24/09/2010

谁能告诉我为什么它返回 0 以及如何排序?

【问题讨论】:

  • 为什么您的日期不存储为DATE 类型?
  • 日期时间函数在数据库系统之间差异很大。如果这只是关于 SQL-Server,请删除 plsqlmysql 标记。
  • 如果您只是在有问题的日期转换会发生什么?
  • 是sql server 2008 R2
  • 是您从实际查询中显示的数据 - 它不是按日期排序的,也不包括您所说的错误字符串(以及标题与问题有什么关系)跨度>

标签: sql sql-server-2008-r2


【解决方案1】:

因为这对我来说很好:

SELECT CONVERT(date,'13/01/2010',103);

试试:

ORDER BY CONVERT(DATE, LEFT(ddate, 10), 103);

我怀疑发生的事情是推送到您的视图中的数据包含您看不到的尾随字符(例如回车)或非打印字符。您可以通过以下方式检查超过 10 个字符的值:

SELECT ... WHERE LEN(ddate) > 10

如果这仍然不起作用,那么可能数据确实很糟糕,例如也许是:

13/O1/2010

在这种情况下,您唯一真正能做的就是一开始就推回表/视图的所有者以获取正确的数据,或者尝试使用以下方法进行过滤:

SET DATEFORMAT DMY;

...
WHERE ISDATE(ddate) = 1

至于您问题中的标题,ISDATE 在这种情况下返回 0,因为默认情况下这不是日期 - 在大多数情况下,SQL Server 是使用美国英语和 MDY 的日期格式设置的,因此它需要日期字符串格式为mm/dd/yyyy13/01/2010 是 2010 年第 13 个月的第一天。我的记忆很粗略,但我可以肯定那年没有第 13 个月。

正如其他人所建议的那样,真正的解决方法是将您的数据存储为日期/时间,而不是字符串,并以明确的格式传入字符串文字,例如YYYYMMDD.

【讨论】:

  • 我已经尝试过了,但也不起作用一件事我只是注意到它返回 0 的所有日期都是大于 12 的日期
  • 如果我尝试 07/12/2011 或 10/01/2012 它返回 true
  • @Vikky ISDATE 不会在 2010 年 1 月 13 日返回 1,除非您 SET DATEFORMAT DMY
  • 影响整个数据库,有没有具体的表方式?
  • @Vikky 它只影响您的会话 - 您从哪里得知它会影响整个数据库?
【解决方案2】:

set dateformat dmy 可能会解决

【讨论】:

    【解决方案3】:

    我猜问题是使用ISDATE() 函数而不是CONVERT()

    你可以试试这个:

    ISDATE( CONVERT(CHAR(10), CONVERT(date, ddate, 103) ) )
    

    但我找不到使用ISDATE() 进行此检查的理由。以上将取决于 DATEFORMAT 设置(可能还有其他我不知道的设置),当CONVERT() 函数发现不兼容的日期时,它将失败并出现错误。


    也许是你能做的最好的破解,如果你不能将日期转换为DATE dataype,在处理日期时应该强调这是最好的做法,是检查这个:

    ISDATE(SUBSTRING(ddate, 7, 4) + SUBSTRING(ddate, 4, 2) + SUBSTRING(ddate, 1, 2))
    

    【讨论】:

    • SELECT ISDATE(CONVERT(CHAR(10), CONVERT(DATE, '13/01/2010', 103))); 对我来说是 0。
    • 如果SET DATEFORMAT DMY,它会失败,奇怪的是。
    • 啊,是的,我应该补充一点,这取决于设置。当日期格式不兼容时,它会失败并出现错误(在CONVERT() 期间)。
    • 是的,我仍然认为此页面上的所有内容都是 hack。解决方法是首先正确存储数据。您永远不必在您存储在 SQL Server 中的日期检查ISDATE()。永远。
    • 感谢您的帮助 aoron 和 @ypercube。你们俩的逻辑都很棒。
    【解决方案4】:

    13/O1/2010 默认美国日期格式转换为第 13 个月的第一天,因此不是有效日期。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-07-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-06-21
      • 2011-03-01
      • 2011-07-01
      • 2011-01-17
      相关资源
      最近更新 更多