我在SQL查询中遇到一个非常奇怪的问题,我收到一条错误消息“从字符串转换日期和/或时间时转换失败。”出乎意料的是(我没想到),但是对查询进行了不同的处理,但有一些工作却没有。因此,我有一个可行的解决方案,但我想了解为什么有些路径无效而有些路径无效。
背景:myTable是具有myDateAsString的表,该表以dd / mm / yyyy格式将日期保存为字符串。无论如何,我无法更改此设置或更改数据库结构,但希望将一些数据作为日期进行处理。
初始数据提取:此方法有效(但没有所需的WHERE子句来缩小数据范围(我希望如果有无法转换的数据会在此处引发错误)
SELECT CONVERT(date, myDateAsString, 103) as myDate
FROM myTable
WHERE子句的添加:我只想提取“将来”的数据。由于上面的查询可以正常工作,所以我希望它也能正常工作,但是会引发错误“从字符串转换日期和/或时间时转换失败。”
SELECT *
FROM (
SELECT CONVERT(date, myDateAsString, 103) as myDate
FROM myTable) as ConvertedData
WHERE myDate > GETDATE()
是否有失败的原因?数据看起来都是正确的日期(尤其是上面的“初始数据提取”查询不会失败。
对于通用表表达式:基于执行顺序等,上述内容似乎(从搜索中发现)可能会失败...因此,我认为CTE有所帮助,并尝试了以下操作
WITH ConvertedData_CTE (myDate)
AS
(
SELECT CONVERT(date, myDateAsString, 103) as myDate
FROM myTable
)
SELECT *
FROM ConvertedData_CTE
WHERE myDate > GETDATE()
再次显示错误消息“从字符串转换日期和/或时间时转换失败。” (注意:如果我删除WHERE子句,则不会显示错误消息)
再尝试一次:因此我尝试使用这样的表变量
DECLARE @ConvertedData TABLE (myDate date)
INSERT INTO @CovertedData (myDate)
SELECT CONVERT(date, myDateAsString, 103) as myDate
FROM myTable
SELECT *
FROM @ConvertedDate
WHERE myDate > GETDATE()
令我惊讶的是,它奏效了。
所以我的问题是为什么最后一个查询有效,但是CTE和内部选择无效?在我看来,这有点反常理,因为我希望它们都能正常工作,但是想更好地理解为什么有些有用,有些却没有。
样本数据
2013年8月22日 2012年10月3日 2013年8月22日 2013年8月24日 2013年8月27日 2013年8月21日 2013年8月23日 15/03/2013 2010/07/04 2013年8月22日 '/ /'
注意:原始表中的数据有3394行,如果我选择前1010行,则可以使所有查询生效;此数据表示行1010到1020,如果我限制原始表的行,则按描述的方式工作...但是,如果我仅使用此数据创建新表...,则查询全部正常 (这对我来说很有意义,因为这就是查询中正在发生的事情;即新表,表变量有效,但其他方法无效) 希望能指出某种正确的方向
编辑:其他信息,最初为了清楚起见没有提供 上面的查询在它们上面都有一个附加的WHERE子句,因为数据库中的某些数据(应该清楚地存储为NULL)存储为'/ /' 因此,在上述所有查询中都有一个附加的WHERE myDateAsString <>'/ /' 注意:我已经将示例数据更新为也包含该数据项,奇怪的是查询仍然可以工作(只有一个“坏数据点”和其中的<>子句可以排除)...问题仍然是为什么排除可以工作在SELECT上发生转换,但是在转换完成后在哪里使用GETDATE()在WHERE上出错?
答案 0 :(得分:1)
我的猜测是您的某些文本日期数据已损坏,或者格式无法转换为日期。要清除此类记录,您可以尝试使用TRY_CONVERT
:
SELECT *
FROM myTable
WHERE TRY_CONVERT(DATETIME, myDateAsString) IS NULL;
一旦发现麻烦的行,则应修复数据,将列转换为日期类型,然后停止将日期信息存储为纯文本。