嵌套case语句中的类型转换问题

时间:2011-07-19 00:32:53

标签: sql sql-server

出现以下(简化和混淆)查询(在我的  mind)从每个可能的返回分支返回一个varchar类型  嵌套案例表达式。我去了铸造第一个的麻烦  两个可能的返回分支到varchar以确保它们的一致性  最后两个可能的返回类型,如最后一个所示  (最深层嵌套的)case语句,它返回字符串。然而,  在运行时,它抱怨尝试将字符串'foo'转换为  INT。一切都运行良好,直到我添加最底层,最多  深度嵌套,case语句总是重写字符串(事实上,  在我添加之前,没有必要进行任何日期转换  因为日期是所有可以返回的)。问题:任何  想法为什么sql server试图转换'foo'字符串(和  可能'bar ...'字符串,如果它可以得到那么远)成为一个int?更多  重要的是,任何有关解决铸造/转换的解决方案的想法  问题?提前谢谢。

select case
         when t1.flubbitz - t1.dubbitz <= 0
         then 
           case
             when (select min(t3.[duedate])
                   from blatz t3  
                     inner join dort t4 on t3.anumerickey = t4.anumerickey 
                   where t4.[somenumbercol] = t2.somenumbercol
                     and t4.somecode = '01'
                       and t3.duedate > getdate()) is not null
             then (select left(convert(varchar, (select min(t3.[duedate])
                   from blatz t3  
                     inner join dort t4 on t3.anumerickey = t4.anumerickey 
                   where t4.[somenumbercol] = t2.somenumbercol
                     and t4.somecode = '01'
                       and t3.duedate > getdate()), 101), 10))
             else 
               case 
                 when (select min(t0.[duedate])
                       from sabtz t0  
                             inner join quux t1 on t0.anumerickey = t1.anumerickey 
                       where t0.somenumbercol = t2.somenumbercol
                         and t0.duedate > getdate()) is not null
                 then (select left(convert(varchar, (select min(t0.[duedate])
                       from sabtz t0  
                             inner join quux t1 on t0.anumerickey = t1.anumerickey 
                       where t0.somenumbercol = t2.somenumbercol
                         and t0.duedate > getdate()), 101), 10))
                     else 
                   case
                     when t2.somenumbercol like 'blub%' then 'foo'
                     when t2.somenumbercol like 'batz%' then 'bar ' + left(convert(varchar, getdate(), 101), 10) 
                   end    
               end 
           end       
         else (select null) 
       end as [Foobar]

from yyy t1 
     inner join xxx t2 on t1.somenumbercol = t2.somenumbercol

where ...

2 个答案:

答案 0 :(得分:2)

这是“(SELECT NULL)”。

在下面的示例中,“(SELECT NULL)”抛出错误,“NULL”不抛出。 “()”将NULL转换为INT。

SELECT CASE -- error
WHEN 3 < 2 THEN 'Hello'
ELSE (SELECT NULL)
END
UNION
SELECT 'Goodbye'

SELECT CASE -- works
WHEN 3 < 2 THEN 'Hello'
ELSE NULL
END
UNION
SELECT 'Goodbye'

SELECT CASE -- works
WHEN 3 < 2 THEN 'Hello'
ELSE CAST(NULL AS VARCHAR)
END
UNION
SELECT 'Goodbye'

答案 1 :(得分:0)

我还没弄清楚为什么会发生这种情况。根据T-SQL文档(http://msdn.microsoft.com/en-us/library/ms181765.aspx),CASE“返回result_expressions中类型集中的最高优先级类型和可选的else_result_expression。”

刚才我发现在没有ELSE条件的情况下,CASE可能默认为INT。 (所有其他CASE语句都有ELSE条件。)为了求知欲,你可以在CASE语句中添加一个ELSE'',看看编译器是否正确地将整个语句解释为char。但我离题了......

当然,重要的是使查询工作,您可以通过将整个CASE语句包装在CAST中来完成,如下所示:

CAST(case
    when t2.somenumbercol like 'blub%' then 'foo'
    when t2.somenumbercol like 'batz%' then 'bar ' + left(convert(varchar, getdate(), 101), 10) 
end AS nvarchar(15))
祝你好运!