SQL Server 无法使用有效字符串将字符串转换为日期时间
Posted
技术标签:
【中文标题】SQL Server 无法使用有效字符串将字符串转换为日期时间【英文标题】:SQL Server fails on converting string to datetime with valid string 【发布时间】:2014-08-06 11:09:43 【问题描述】:我正在将一些旧的、格式严重的数据迁移到新系统,并从字符串列中的大量数据中提取到期日期。它的格式为<Something>Data</>
(不是我做的,我会补充!)
我需要提取的元素之一是到期日期/时间。我这样做如下:
SELECT convert(datetime,
SUBSTRING(EventData,
CHARINDEX('<ExpiryDate>', EventData, 0) + 12,
CHARINDEX('</>', EventData, CHARINDEX('<ExpiryDate>', EventData, 0)) - (CHARINDEX('<ExpiryDate>', EventData, 0) + 12)
),
103)
这在大多数情况下都可以正常工作,虽然有点慢,但在某些数据上我得到了错误:
从字符转换日期和/或时间时转换失败 字符串。
如果子字符串返回格式不正确的日期/时间,这将是有意义的,但它们对我来说似乎都很好。确保顺序,处理以下行,最后一个失败:
<ExpiryDate>22/03/2010 17:00:00</>
<ExpiryDate>22/03/2010 17:00:00</>
<ExpiryDate>22/03/2010 17:00:00</>
<ExpiryDate>22/03/2010 17:00:00</>
子字符串非常高兴地解析它们如下:
22/03/2010 17:00:00
22/03/2010 17:00:00
22/03/2010 17:00:00
22/03/2010 17:00:00
这四个中的最后一个会失败有什么原因吗?或者有没有更健壮的方法来解析它们?
编辑:更多调查揭示了一个奇怪之处:如果我不 CONVERT() 内联,而是只分配子字符串的输出,并将其用作 CTE,然后执行 CONVERT(),它就可以工作正好。数据类型有些不对劲。
【问题讨论】:
可能不相关,但您是否有理由不转换为datetime2
?
【参考方案1】:
我在 SQL Server 2012 上尝试过,效果很好。 CONVERT 日期格式 103 是正确的。以下代码是否适用于您的数据库?
DECLARE @MyString CHAR(100)
SET @MyString = '<ExpiryDate>22/03/2010 17:00:00</>'
SELECT convert(datetime,
SUBSTRING(@MyString,
CHARINDEX('<ExpiryDate>', @MyString, 0) + 12,
CHARINDEX('</>', @MyString, CHARINDEX('<ExpiryDate>', @MyString, 0)) -
(CHARINDEX('<ExpiryDate>', @MyString, 0) + 12)
)
, 103)
【讨论】:
它确实有效,是的。那是奇怪的事情。除了直接拉它之外的任何东西似乎都可以正常工作。不过,我注意到的是,如果我将子字符串输出设置为列内容,使用 WITH 子句对其进行分配,然后再进行转换就可以了。这让我觉得存在数据类型问题。 抱歉,如果没有生成数据的错误,我无法为您提供任何帮助。据我所知,您的代码是 100% 正确的。我也会调查数据本身。也许某个地方的隐形字符(TAB、CR、LF、...)?似乎您已经通过使用 CTE 找到了解决方案。正如 Daniel B 提到的,您可以使用 datatime2。它比日期时间有一些优势。以上是关于SQL Server 无法使用有效字符串将字符串转换为日期时间的主要内容,如果未能解决你的问题,请参考以下文章
Sqoop Hive 字符串数据类型转 MS SQL Server 类型
经典 ASP - 使用 Windows 身份验证的 SQL Server 2008 连接字符串
如何通过 SQL Server 插入的索引有效地替换长字符串?