2011-03-25 72 views
1

我正在查询应用程序的后端。出于何种原因,开发人员决定在所有领域使用NVARCHAR。我遇到了一个“日期”字段的问题 - 不知何故,它填充了“97630886”。有一个伴侣“时间”字段,对于我试图连接并查询结果为DATETIME的查询。我试图使用CASE语句,但它是错误的:“将char数据类型转换为日期时间数据类型导致超出范围的日期时间值。”显然所有的条件都被评估?有没有一种方法可以重写我的SELECT语句来处理这个问题?SELECT CASE CAST转换错误

SELECT CASE 
WHEN LOG_DATE IS NULL AND LOG_TIME IS NULL THEN NULL 
WHEN LOG_DATE IS NULL THEN LOG_TIME 
WHEN LOG_TIME IS NULL THEN LOG_DATE 
WHEN ISDATE(LOG_DATE) = 0 OR ISDATE(LOG_TIME) = 0 THEN LOG_DATE + ' ' + LOG_TIME 
ELSE CAST(LOG_DATE + ' ' + LOG_TIME AS DATETIME) 
END AS [LogDateTime] 
FROM ... 
+0

如果LOG_DATE包含“97630886”,为什么你期望它能够工作?如果ISDATE(LOG_DATE)= 0或ISDATE(LOG_TIME)= 0 THEN LOG_DATE +''+ LOG_TIME'?不管什么'LOG_TIME'包含它永远不会连接成一个将成功作为日期时间转换的东西? – 2011-03-25 14:32:13

+0

我的想法是,如果两个字段都没有SQL Server将某个日期识别为日期,那么我只需将它们连接在一起并返回即可 - 某些数据总比没有数据好。因为ISDATE('97630886')= 0 – SLeepdepD 2011-03-25 14:33:55

+0

您不能从case语句的不同路径返回不同的'datatypes'。 SQL Server将采用具有最高数据类型优先级的数据类型,并隐含地转换为该数据类型(“DATETIME”的优先级高于'varchar')。 'sql_variant'具有比'varchar'和'datetime'更高的优先级,尽管... – 2011-03-25 14:36:03

回答

3

(不照顾,他们将隐式转换OK或至少)时像下面的SQL Server中的stament面临将使用数据类型优先级来确定

不能混合在CASE表达式数据类型表达的整体数据类型应该是什么

SELECT CASE WHEN 1=1 THEN 'not-a-date' ELSE getdate() END 

对于上述datetime的优先级高于char所以它隐含铸串到失败的日期。然而

如下因素作为成功sql_varianthas a higher precedence

SELECT CASE WHEN 1=1 THEN cast('not-a-date' as sql_variant) ELSE getdate() END 

所以,你可以返回多个混合数据类型那样(我不知道sql_variant是多么容易,虽然工作)

比你其他可能会返回NULL以获取无效的日期时间,而不是返回无意义的数据或将所有内容都转换为字符串,如果必须将其返回。