SQL Server 2008 r2 CASE表达式未正确评估

时间:2013-05-23 17:57:47

标签: sql sql-server sql-server-2008-r2 case

我有以下SQL语句,它不确定何时字段的值为'Y'。这是SQL ...

SELECT A.BUSINESS_UNIT 
 , A.WO_ID 
 , A.WO_TASK_ID 
 , A.ENS_TSK_CRT_VAL 
 , (CASE WHEN A.ENS_TSK_CRT_V01 = 'Y' THEN B.DESCR ELSE ' ' END) AS ENS_TSK_CRT_V01  
 , (CASE WHEN A.ENS_TSK_CRT_V02 = 'Y' THEN C.DESCR ELSE ' ' END) AS ENS_TSK_CRT_V02 
 , (CASE WHEN A.ENS_TSK_CRT_V03 = 'Y' THEN D.DESCR ELSE ' ' END) AS ENS_TSK_CRT_V03  
 , (CASE WHEN A.ENS_TSK_CRT_V04 = 'Y' THEN E.DESCR ELSE ' ' END) AS ENS_TSK_CRT_V04 
 , (CASE WHEN A.ENS_TSK_CRT_V05 = 'Y' THEN F.DESCR ELSE ' ' END) AS ENS_TSK_CRT_V05 
 , (CASE WHEN A.ENS_TSK_CRT_V06 = 'Y' THEN G.DESCR ELSE ' ' END) AS ENS_TSK_CRT_V06 
 , (CASE WHEN A.ENS_TSK_CRT_V07 = 'Y' THEN H.DESCR ELSE ' ' END) AS ENS_TSK_CRT_V07 
 , (CASE WHEN A.ENS_TSK_CRT_V08 = 'Y' THEN I.DESCR ELSE ' ' END) AS ENS_TSK_CRT_V08 
 FROM PS_ENS_WM_TSKCR_VW A LEFT OUTER JOIN ( 
   SELECT A.BUSINESS_UNIT 
   , A.WO_TASK_ID 
   , C.DESCR 
   , A.WO_ID 
    , C.ENS_TSK_CRT_CD 
     FROM PS_ENS_WM_TSKCR_VW A 
     , PS_ENS_WM_TSK_CRT C 
    WHERE A.ENS_TSK_CRT_V01 = 'Y' 
      AND C.SETID = 'SHARE' 
      AND C.ENS_TSK_CRT_CD = '01' ) B ON B.BUSINESS_UNIT = A.BUSINESS_UNIT 
      AND B.WO_ID = A.WO_ID 
      AND B.WO_TASK_ID = A.WO_TASK_ID LEFT OUTER JOIN ( 
    SELECT A.BUSINESS_UNIT 
    , A.WO_TASK_ID 
    , C.DESCR 
    , A.WO_ID 
    , C.ENS_TSK_CRT_CD 
     FROM PS_ENS_WM_TSKCR_VW A 
     , PS_ENS_WM_TSK_CRT C 
    WHERE A.ENS_TSK_CRT_V01 = 'Y' 
      AND C.SETID = 'SHARE' 
      AND C.ENS_TSK_CRT_CD = '02' ) C ON C.BUSINESS_UNIT = A.BUSINESS_UNIT 
      AND C.WO_ID = A.WO_ID 
      AND C.WO_TASK_ID = A.WO_TASK_ID LEFT OUTER JOIN ( 
    SELECT A.BUSINESS_UNIT 
    , A.WO_TASK_ID 
    , C.DESCR 
    , A.WO_ID 
    , C.ENS_TSK_CRT_CD 
     FROM PS_ENS_WM_TSKCR_VW A 
     , PS_ENS_WM_TSK_CRT C 
    WHERE A.ENS_TSK_CRT_V01 = 'Y' 
      AND C.SETID = 'SHARE' 
      AND C.ENS_TSK_CRT_CD = '03' ) D ON D.BUSINESS_UNIT = A.BUSINESS_UNIT 
      AND D.WO_ID = A.WO_ID 
      AND D.WO_TASK_ID = A.WO_TASK_ID LEFT OUTER JOIN ( 
    SELECT A.BUSINESS_UNIT 
    , A.WO_TASK_ID 
    , C.DESCR 
    , A.WO_ID 
    , C.ENS_TSK_CRT_CD 
     FROM PS_ENS_WM_TSKCR_VW A 
     , PS_ENS_WM_TSK_CRT C 
    WHERE A.ENS_TSK_CRT_V01 = 'Y' 
      AND C.SETID = 'SHARE' 
      AND C.ENS_TSK_CRT_CD = '04' ) E ON E.BUSINESS_UNIT = A.BUSINESS_UNIT 
             AND E.WO_ID = A.WO_ID 
      AND E.WO_TASK_ID = A.WO_TASK_ID LEFT OUTER JOIN ( 
    SELECT A.BUSINESS_UNIT 
    , A.WO_TASK_ID 
    , C.DESCR 
    , A.WO_ID 
    , C.ENS_TSK_CRT_CD 
     FROM PS_ENS_WM_TSKCR_VW A 
     , PS_ENS_WM_TSK_CRT C 
    WHERE A.ENS_TSK_CRT_V01 = 'Y' 
      AND C.SETID = 'SHARE' 
      AND C.ENS_TSK_CRT_CD = '05' ) F ON F.BUSINESS_UNIT = A.BUSINESS_UNIT 
      AND F.WO_ID = A.WO_ID 
      AND F.WO_TASK_ID = A.WO_TASK_ID LEFT OUTER JOIN ( 
    SELECT A.BUSINESS_UNIT 
    , A.WO_TASK_ID 
    , C.DESCR 
    , A.WO_ID 
    , C.ENS_TSK_CRT_CD 
     FROM PS_ENS_WM_TSKCR_VW A 
     , PS_ENS_WM_TSK_CRT C 
    WHERE A.ENS_TSK_CRT_V01 = 'Y' 
      AND C.SETID = 'SHARE' 
      AND C.ENS_TSK_CRT_CD = '06' ) G ON G.BUSINESS_UNIT = A.BUSINESS_UNIT 
      AND G.WO_ID = A.WO_ID 
      AND G.WO_TASK_ID = A.WO_TASK_ID LEFT OUTER JOIN ( 
    SELECT A.BUSINESS_UNIT 
    , A.WO_TASK_ID 
    , C.DESCR 
    , A.WO_ID 
    , C.ENS_TSK_CRT_CD 
     FROM PS_ENS_WM_TSKCR_VW A 
     , PS_ENS_WM_TSK_CRT C 
    WHERE A.ENS_TSK_CRT_V01 = 'Y' 
      AND C.SETID = 'SHARE' 
      AND C.ENS_TSK_CRT_CD = '07' ) H ON H.BUSINESS_UNIT = A.BUSINESS_UNIT 
      AND H.WO_ID = A.WO_ID 
      AND H.WO_TASK_ID = A.WO_TASK_ID LEFT OUTER JOIN ( 
    SELECT A.BUSINESS_UNIT 
    , A.WO_TASK_ID 
    , C.DESCR 
    , A.WO_ID 
    , C.ENS_TSK_CRT_CD 
     FROM PS_ENS_WM_TSKCR_VW A 
     , PS_ENS_WM_TSK_CRT C 
    WHERE A.ENS_TSK_CRT_V01 = 'Y' 
      AND C.SETID = 'SHARE' 
      AND C.ENS_TSK_CRT_CD = '08' ) I ON I.BUSINESS_UNIT = A.BUSINESS_UNIT 
      AND I.WO_ID = A.WO_ID 
      AND I.WO_TASK_ID = A.WO_TASK_ID  
    WHERE ( A.ENS_TSK_CRT_VAL <> 0 
    AND A.WO_ID = '0000002151'
    AND A.BUSINESS_UNIT = 'R3851' )

案例陈述有时会提取'Y'并按预期行事,有时则不然。正在检查“Y”值的字段是长度为一个字符的CHAR字段。我已经尝试过转换和转换,以确保在与'Y'相比时,该值是我在case语句中所期望的。我试过连接'&gt;'和'&lt;'到任何一方,看看是否有空格填充该值,而事实并非如此。看起来好像案例陈述只是停止了工作。以下是数据外观的一个小样本,让您了解它的工作原理...对不起它有点乱。

WO_TASK_ID  WO_ID   ENS_TSK_CRT_VAL ENS_TSK_CRT_V01 ENS_TSK_CRT_V02 ENS_TSK_CRT_V03
1           0000002151     2    Y   N   N
9           0000002151   12 N   Y   Y
12          0000002151     52   N   Y   N

我已经通过采取完全不同的路线解决了问题,但我只是想知道这是怎么回事,以及如何在将来再次使用CASE Expression时克服这个问题。

非常感谢任何帮助...

  • 弗林

4 个答案:

答案 0 :(得分:1)

这可能对你有所帮助 -

;WITH cte AS 
(
    SELECT  A.BUSINESS_UNIT ,
            A.WO_TASK_ID ,
            C.DESCR ,
            A.WO_ID ,
            C.ENS_TSK_CRT_CD
    FROM PS_ENS_WM_TSKCR_VW A ,
         PS_ENS_WM_TSK_CRT C
    WHERE A.ENS_TSK_CRT_V01 = 'Y'
        AND C.SETID = 'SHARE'
        AND C.ENS_TSK_CRT_CD IN (
                    '01', '02', '03', '04', 
                    '05', '06', '07', '08'
                )
)
SELECT  A.BUSINESS_UNIT ,
        A.WO_ID ,
        A.WO_TASK_ID ,
        A.ENS_TSK_CRT_VAL ,
        ISNULL(B.DESCR, ' ') AS ENS_TSK_CRT_V01 ,
        ISNULL(C.DESCR, ' ') AS ENS_TSK_CRT_V02 ,
        ISNULL(D.DESCR, ' ') AS ENS_TSK_CRT_V03 ,
        ISNULL(E.DESCR, ' ') AS ENS_TSK_CRT_V04 ,
        ISNULL(F.DESCR, ' ') AS ENS_TSK_CRT_V05 ,
        ISNULL(G.DESCR, ' ') AS ENS_TSK_CRT_V06 ,
        ISNULL(H.DESCR, ' ') AS ENS_TSK_CRT_V07 ,
        ISNULL(I.DESCR, ' ') AS ENS_TSK_CRT_V08
FROM PS_ENS_WM_TSKCR_VW A
LEFT JOIN cte B ON B.BUSINESS_UNIT = A.BUSINESS_UNIT
    AND B.WO_ID = A.WO_ID
    AND B.WO_TASK_ID = A.WO_TASK_ID
    AND B.ENS_TSK_CRT_CD = '01'
    AND A.ENS_TSK_CRT_V01 = 'Y'
LEFT JOIN cte C ON C.BUSINESS_UNIT = A.BUSINESS_UNIT
    AND C.WO_ID = A.WO_ID
    AND C.WO_TASK_ID = A.WO_TASK_ID
    AND C.ENS_TSK_CRT_CD = '02'
    AND A.ENS_TSK_CRT_V02 = 'Y'
LEFT JOIN cte D ON D.BUSINESS_UNIT = A.BUSINESS_UNIT
    AND D.WO_ID = A.WO_ID
    AND D.WO_TASK_ID = A.WO_TASK_ID
    AND D.ENS_TSK_CRT_CD = '03'
    AND A.ENS_TSK_CRT_V03 = 'Y'
LEFT JOIN cte E ON E.BUSINESS_UNIT = A.BUSINESS_UNIT
    AND E.WO_ID = A.WO_ID
    AND E.WO_TASK_ID = A.WO_TASK_ID
    AND E.ENS_TSK_CRT_CD = '04'
    AND A.ENS_TSK_CRT_V04 = 'Y'
LEFT JOIN cte F ON F.BUSINESS_UNIT = A.BUSINESS_UNIT
    AND F.WO_ID = A.WO_ID
    AND F.WO_TASK_ID = A.WO_TASK_ID
    AND F.ENS_TSK_CRT_CD = '05'
    AND A.ENS_TSK_CRT_V05 = 'Y'
LEFT JOIN cte G ON G.BUSINESS_UNIT = A.BUSINESS_UNIT
    AND G.WO_ID = A.WO_ID
    AND G.WO_TASK_ID = A.WO_TASK_ID
    AND G.ENS_TSK_CRT_CD = '06'
    AND A.ENS_TSK_CRT_V06 = 'Y'
LEFT JOIN cte H ON H.BUSINESS_UNIT = A.BUSINESS_UNIT
    AND H.WO_ID = A.WO_ID
    AND H.WO_TASK_ID = A.WO_TASK_ID
    AND H.ENS_TSK_CRT_CD = '07'
    AND A.ENS_TSK_CRT_V07 = 'Y'
LEFT JOIN cte I ON I.BUSINESS_UNIT = A.BUSINESS_UNIT
    AND I.WO_ID = A.WO_ID
    AND I.WO_TASK_ID = A.WO_TASK_ID
    AND I.ENS_TSK_CRT_CD = '08'
    AND A.ENS_TSK_CRT_V08 = 'Y'
WHERE A.ENS_TSK_CRT_VAL != 0
    AND A.WO_ID = '0000002151'
    AND A.BUSINESS_UNIT = 'R3851'

答案 1 :(得分:1)

BTW,以防万一有人好奇,这是我在将CASE Expression的问题发布到原始问题之前使用的解决方法......

SELECT A.BUSINESS_UNIT , A.WO_ID , A.WO_TASK_ID , A.ENS_TSK_CRT_VAL 
 , (CASE WHEN (CASE WHEN CAST(A.ENS_TSK_CRT_VAL AS INT) & POWER(2,1) > 0 THEN 1 ELSE 0 END) = 1 THEN (SELECT DESCR FROM PS_ENS_WM_TSK_CRT WHERE ENS_TSK_CRT_CD = 01 AND SETID = 'SHARE') ELSE ' ' END) AS ENS_TSK_CRT_VAL01
 , (CASE WHEN (CASE WHEN CAST(A.ENS_TSK_CRT_VAL AS INT) & POWER(2,2) > 0 THEN 1 ELSE 0 END) = 1 THEN (SELECT DESCR FROM PS_ENS_WM_TSK_CRT WHERE ENS_TSK_CRT_CD = 02 AND SETID = 'SHARE') ELSE ' ' END) AS ENS_TSK_CRT_VAL02
 , (CASE WHEN (CASE WHEN CAST(A.ENS_TSK_CRT_VAL AS INT) & POWER(2,3) > 0 THEN 1 ELSE 0 END) = 1 THEN (SELECT DESCR FROM PS_ENS_WM_TSK_CRT WHERE ENS_TSK_CRT_CD = 03 AND SETID = 'SHARE') ELSE ' ' END) AS ENS_TSK_CRT_VAL03
 , (CASE WHEN (CASE WHEN CAST(A.ENS_TSK_CRT_VAL AS INT) & POWER(2,4) > 0 THEN 1 ELSE 0 END) = 1 THEN (SELECT DESCR FROM PS_ENS_WM_TSK_CRT WHERE ENS_TSK_CRT_CD = 04 AND SETID = 'SHARE') ELSE ' ' END) AS ENS_TSK_CRT_VAL04
 , (CASE WHEN (CASE WHEN CAST(A.ENS_TSK_CRT_VAL AS INT) & POWER(2,5) > 0 THEN 1 ELSE 0 END) = 1 THEN (SELECT DESCR FROM PS_ENS_WM_TSK_CRT WHERE ENS_TSK_CRT_CD = 05 AND SETID = 'SHARE') ELSE ' ' END) AS ENS_TSK_CRT_VAL05
 , (CASE WHEN (CASE WHEN CAST(A.ENS_TSK_CRT_VAL AS INT) & POWER(2,6) > 0 THEN 1 ELSE 0 END) = 1 THEN (SELECT DESCR FROM PS_ENS_WM_TSK_CRT WHERE ENS_TSK_CRT_CD = 06 AND SETID = 'SHARE') ELSE ' ' END) AS ENS_TSK_CRT_VAL06
 , (CASE WHEN (CASE WHEN CAST(A.ENS_TSK_CRT_VAL AS INT) & POWER(2,7) > 0 THEN 1 ELSE 0 END) = 1 THEN (SELECT DESCR FROM PS_ENS_WM_TSK_CRT WHERE ENS_TSK_CRT_CD = 07 AND SETID = 'SHARE') ELSE ' ' END) AS ENS_TSK_CRT_VAL07
 , (CASE WHEN (CASE WHEN CAST(A.ENS_TSK_CRT_VAL AS INT) & POWER(2,8) > 0 THEN 1 ELSE 0 END) = 1 THEN (SELECT DESCR FROM PS_ENS_WM_TSK_CRT WHERE ENS_TSK_CRT_CD = 08 AND SETID = 'SHARE') ELSE ' ' END) AS ENS_TSK_CRT_VAL08
 FROM PS_ENS_WM_TSKCR_WO A 
WHERE A.ENS_TSK_CRT_VAL <> 0
AND A.WO_ID = '0000002151' AND A.BUSINESS_UNIT = 'R3851'

答案 2 :(得分:0)

我怀疑这是案例陈述的行为。我刚刚发现2008 R2与2005年的差异,在我的搜索中发现了你的问题。案例由sql server 2008 R2处理,与2005不同。请注意2008年文档备注中的声明:“在某些情况下,在CASE语句接收表达式的结果作为其输入之前计算表达式。评估这些表达式的错误是可能的。”

因此,在2008年,即使不合适(输入也不评估为真),所有潜在产出都可能被评估,这在我升级到2008年后的一些存储过程中就会出现。

所以也许在你的情况下,无论B.DESCR,C.DESCR,D.DESCR等是否等于'Y', B.DESCR,C.DESCR,D.DESCR等得到评估,并且当时可能为空或以其他方式无法与'Y'进行比较,从而导致该部分陈述失败(这似乎是沉默的)。不确定,但它的味道和我遇到的问题一样。唯一让我对这个“答案”持谨慎态度的是我的问题是在where子句中,而你的问题是在sql语句的select部分。

无论如何,也许有人会觉得这很有帮助。需要花一些时间来解决这个问题。

答案 3 :(得分:-1)

您可以尝试从Y中删除可能导致类似问题的尾随空格