我试图从临时表中提取某些日期的数据,而临时开发人员导入了文件中的所有内容,因此我需要过滤掉非数据"行并将剩余的字符串转换为datetime。
哪个应该足够简单但是...我一直收到这个错误:
将varchar数据类型转换为日期时间数据类型会导致超出范围的值。
我已经接受了查询并将其拆开,确保没有无效的字符串,甚至尝试了一些不同的查询配置。这就是我现在所拥有的:
SELECT *
FROM
(
select cdt = CAST(cmplt_date as DateTime), *
from stage_hist
WHERE cmplt_date NOT LIKE '(%'
AND ltrim(rtrim(cmplt_date)) NOT LIKE ''
AND cmplt_date NOT LIKE '--%'
) f
WHERE f.cdt BETWEEN '2017-09-01' AND '2017-10-01'
为了确保转换至少有效,我可以运行内部查询,并且转换实际上适用于所有行。我获得了行的有效数据集而没有错误,因此实际的转换工作正常。
BETWEEN语句必须抛出错误,对吗?但是我已经成功地使用了两个字符串,甚至从表中获取了一个值并使用它进行了测试查询,这也成功地运行了:
select 1
WHERE CAST(' 2017-09-26' as DateTime) BETWEEN '2017-09-01' AND '2017-10-01'
因此,如果所有演员都是单独工作的,那么在运行真实查询时我怎么会出现超出范围的错误?
答案 0 :(得分:1)
我猜这是因为在cmplt_date
字段中存在的值不是有效日期。是的,我知道您使用WHERE
子句过滤它们,但知道Logical Processing Order of the SELECT statement并不总是实际的顺序。这意味着有时候SQL Engine会在完成过滤之前开始执行CAST
操作。
您使用的是SQL Server 2012
,因此您只需添加TRY_CAST:
SELECT *
FROM
(
select cdt = TRY_CAST(cmplt_date as DateTime), *
from stage_hist
WHERE cmplt_date NOT LIKE '(%'
AND ltrim(rtrim(cmplt_date)) NOT LIKE ''
AND cmplt_date NOT LIKE '--%'
) f
WHERE f.cdt BETWEEN '2017-09-01' AND '2017-10-01'