【问题标题】:SQL Server 2000 trouble converting nvarchar to datetimeSQL Server 2000 无法将 nvarchar 转换为日期时间
【发布时间】:2011-09-01 03:01:28
【问题描述】:

在一个表中有一个数据类型为 datetime 的列,我需要将该列中的数据与当前日期和时间进行比较。

我正在尝试在现场进行转换,但我收到了

Syntax error converting datetime from character string

不幸的是,列中的值具有三种不同的格式(旧版垃圾)

November 28, 2005 -or-
5/1/2011 12:00:00 AM -or-
null

我使用的代码如下:

SELECT 1 from webprograms where convert(datetime, ApplicationDueDate) < getdate()

谁能帮忙诊断一下问题

【问题讨论】:

  • 数据中的'null'是字符串还是记录实际上是NULL

标签: sql datetime sql-server-2000


【解决方案1】:

您可以转换到较新版本的 SQL Server 吗?如果是这样,问题就会自行解决。如果不是,您必须从等式中排除空值,因为它们是这里的问题。

我认为您的前 1 名是否选择空值并不重要,因为我认为评估失败,因为该列可以为空。我在 SQL Server 2008 R2 中做了一个快速测试,它运行良好。

【讨论】:

  • 我们正在转换,但暂时不会。这需要在此之前完成,因为我们转换的日期是未知的。我也尝试过添加 NOT ApplicationDueDate IS NULL 子句,但仍然收到错误
  • 哦,我把 1 放在那里只是为了使查询简单,它与我实际返回的内容无关
  • @matt - 根据他的回答,只有当列接受NULL 时才重要,而不是任何数据实际上是。
  • 是的,除了空值之外,该列确实存在,我尝试使用 NOT ApplicationDueDate IS NULL (和其他语法)排除空值,并尝试转换为假日期(即 ISNULL(ApplicationDueDate, '01/ 01/1900')) 但这也没有用
  • null 字符串将转换为日期时间。不过,它将是 null 日期时间。零字符串 ('') 将转换为 1 Jan 1900 00:00:00.000
【解决方案2】:

这两种日期格式都可以很好地转换。默认的convert 算法在灵活处理给出的内容方面做得相当不错。还有一个null 字符串,正如我之前评论的, will always convert to anulldatetime value: per the standard, any expression that involvingnullyieldsnull`。

我怀疑您遇到了数据问题。最有可能的垃圾字符,如嵌入式 CR、LF 或 CR+LF(换行符)。 HT(制表符)字符似乎也破坏了convert()。您(或您的 DBA)可能需要进行数据清理以消除垃圾字符。或者你需要解决这个问题并编写一个丑陋的表达式来修复运行时的坏数据。

这样的查询应该可以识别问题数据:

select myCruftyDateTimeColumn,count(*)
from foo
where myCruftyDateTimeColumn is not null
  -- m/d/yyyy hh:mm:ss AM format
  and myCruftyDateTimeColumn not like '[0-9][0-9]/[0-9][0-9]/[0-9][0-9][0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9] [AP]M'
  and myCruftyDateTimeColumn not like '[0-9][0-9]/[0-9]/[0-9][0-9][0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9] [AP]M'
  and myCruftyDateTimeColumn not like '[0-9]/[0-9]/[0-9][0-9][0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9] [AP]M'
  -- month d, yyyy alternatives, 2 digit days
  and myCruftyDateTimeColumn not like 'January [0-9][0-9], [0-9][0-9][0-9][0-9]'
  and myCruftyDateTimeColumn not like 'February [0-9][0-9], [0-9][0-9][0-9][0-9]'
  and myCruftyDateTimeColumn not like 'March [0-9][0-9], [0-9][0-9][0-9][0-9]'
  and ...
  and myCruftyDateTimeColumn not like 'October [0-9][0-9], [0-9][0-9][0-9][0-9]'
  and myCruftyDateTimeColumn not like 'November [0-9][0-9], [0-9][0-9][0-9][0-9]'
  and myCruftyDateTimeColumn not like 'December [0-9][0-9], [0-9][0-9][0-9][0-9]'
  -- month d, yyyy alternatives, 2 digit days
  and myCruftyDateTimeColumn not like 'January [0-9], [0-9][0-9][0-9][0-9]'
  and myCruftyDateTimeColumn not like 'February [0-9], [0-9][0-9][0-9][0-9]'
  and myCruftyDateTimeColumn not like 'March [0-9], [0-9][0-9][0-9][0-9]'
  and ...
  and myCruftyDateTimeColumn not like 'October [0-9], [0-9][0-9][0-9][0-9]'
  and myCruftyDateTimeColumn not like 'November [0-9], [0-9][0-9][0-9][0-9]'
  and myCruftyDateTimeColumn not like 'December [0-9], [0-9][0-9][0-9][0-9]'
group by myCruftyDateTimeColumn
order by 1

您可能希望加载一个带有结果的临时表,然后从中加载

select *,convert(varbinary,myCruftyDateTimeColumn)
from #bad_data

准确识别假字符是什么。

【讨论】:

  • LOL 这就是我现在是“DBA”的问题。曾经运行此操作的老人不知道他在做什么(到处都是冗余和空列)我正在学习
  • 好的,我实际上通过该查询返回了 27 行数据。不过,退回的物品看起来都不错。它们是有效日期或有效日期和时间
  • 我还将结果转储到临时表中,第三列给了我类似“0x4400650063002E002000310035002C0020003200300030003800”的内容
  • 啊哈!!!有 6 个日期要么缩写,要么拼写错误,在一种情况下,逗号和年份之间没有空格
  • 它不会关心逗号和年份之间的空格。它也不会介意 3 个字符的月份缩写("Jan 12,2009" 可以正常工作,非常感谢,但对于 "Janu 12, 2009" 之类的东西就不那么重要了)。并且拼写错误的月份名称是正确的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-04-29
  • 2021-05-27
  • 1970-01-01
  • 2015-09-23
  • 2021-01-17
  • 2014-03-01
  • 2015-12-16
相关资源
最近更新 更多