我以前遇到过这种类型的错误,这是由于执行计划执行的“操作顺序”造成的。
您收到该错误消息是因为语句的执行计划(由优化器生成)正在对包含无法转换为 DATETIME 的字符串值的行执行 CONVERT() 操作。
基本上,您无法控制优化器对哪些行执行转换。您知道您只需要对某些行进行转换,并且您有排除这些行的谓词(WHERE 或 ON 子句)(将这些行限制为需要转换的行),但您的执行计划正在执行 CONVERT() 操作在排除这些行之前的行。
(例如,优化器可能会选择进行表扫描,并在应用任何谓词之前对每一行执行该转换。)
如果没有具体问题和生成错误的具体 SQL,我无法给出具体答案。
解决该问题的一种简单方法是使用 ISDATE() 函数来测试字符串值是否可以转换为日期。
即替换:
CONVERT(DATETIME,eav.Value)
with:
CASE WHEN ISDATE(eav.Value) > 0 THEN CONVERT(DATETIME, eav.Value) ELSE NULL END
or:
CONVERT(DATETIME, CASE WHEN ISDATE(eav.Value) > 0 THEN eav.Value ELSE NULL END)
请注意,ISDATE() 函数受到一些重大限制,例如受会话的 DATEFORMAT 和 LANGUAGE 设置的影响。
如果 eav 行上有其他指示,您可以使用其他测试来有条件地执行转换。
CASE WHEN eav.ValueIsDateTime=1 THEN CONVERT(DATETIME, eav.Value) ELSE NULL END
我使用的另一种方法是尝试使用内联视图或公共表表达式来尝试对优化器的操作顺序进行一定程度的控制,并使用强制优化器具体化它们并应用谓词的操作,以便在之前发生这种情况外部查询中的任何转换。