将嵌套解码转换为等效的CASE语句(从Oracle转换为PostgreSQL所需)

问题描述 投票:0回答:3

我在Oracle 11.2.0.4上。我有一个嵌套的DECODE语句,我需要转换为CASE语句。有人可以提供帮助。我不确定它是如何完成的,事实上我并不完全理解它的逻辑。如果有人能够解释它基本上打算做什么,那么使用CASE重写的功能对我来说非常有用。这是函数...(注意:不要担心表连接,有3个表和一个条件等,请关注DECODE及其转换为CASE)。此外,我必须手动转换,工具不是一个选项。

CREATE OR REPLACE FUNCTION TMP_Func
   RETURN NUMBER
IS
   V   NUMBER;
BEGIN
   SELECT DECODE (
             NVL (tab1.flag1, '~'),
             'D', DECODE (tab1.code_oid, NVL (tab3.bu_id, '-'), 1, 0),
             'C', DECODE (tab1.code_oid, NVL (tab3.cost_id, '-'), 1, 0),
             DECODE (tab2.oid,
                     DECODE (tab1.co_id, NULL, tab2.oid, tab1.co_id), 1,
                     0))
     INTO V
     FROM tab1, tab2, tab3
    WHERE tab2.OID = tab1.sec_id;

   RETURN V;
END;
sql oracle postgresql case
3个回答
1
投票

那将是这样的:

SELECT CASE
          WHEN NVL (tab1.flag1, '~') = 'D'
          THEN
             CASE
                WHEN tab1.code_oid = NVL (tab3.bu_id, '-') THEN 1
                ELSE 0
             END
          WHEN NVL (tab1.flag1, '~') = 'C'
          THEN
             CASE
                WHEN tab1.code_oid = NVL (tab3.cost_id, '-') THEN 1
                ELSE 0
             END
          ELSE
             CASE
                WHEN tab2.oid =
                        CASE
                           WHEN tab1.co_id IS NULL THEN tab2.oid
                           ELSE tab1.co_id
                        END
                THEN
                   1
                ELSE
                   0
             END
       END
  INTO v
  FROM ...

请注意,您的FROM子句包含3个表,但WHERE只包含其中两个。怎么样tab3?另外,请考虑切换到ANSI连接。


1
投票

这样的事情:

select CASE WHEN COALESCE(tab1.flag1,'~') = 'D' THEN 
            CASE WHEN tab1.code_oid=COALESCE(tab3.bu_id, '-') THEN 1 else 0 end

        WHEN COALESCE(tab1.flag1,'~')='C' THEN 
            CASE WHEN tab1.code_oid=COALESCE(tab3.cost_id, '-') THEN 1 else 0 end

        else 
            CASE WHEN tab2.oid=COALESCE(tab1.co_id,tab2.oid) THEN 1 else 0 end
        end
        FROM tab1, tab2, tab3
    WHERE tab2.OID = tab1.sec_id;

NVL由COALESCE取代

DECODE(a,b,c,d,e,...,f)被替换为:

  CASE WHEN a=b THEN c
       WHEN a=d THEN e
       ...
       else f 
   end 

你的上一次解码(DECODE(tab1.co_id,NULL,tab2.oid,tab1.co_id),1,0)))实际上是一个NVL(tab1.co_id,tab2.oid)


1
投票

以下应该做你想要的:

SELECT CASE COALESCE(TAB1.FLAG1, '~')
         WHEN 'D' THEN CASE
                         WHEN TAB1.CODE_OID = COALESCE(TAB3.BU_ID, '-') THEN 1
                         ELSE 0
                       END
         WHEN 'C' THEN CASE
                         WHEN TAB1.CODE_OID = COALESCE(TAB3.COST_ID, '~') THEN 1
                         ELSE 0
                       END
         ELSE CASE
                WHEN TAB2.OID = COALESCE(TAB1.CO_ID, TAB2.OID) THEN 1
                ELSE 0
              END
       END
  INTO V
  FROM TAB1
  INNER JOIN TAB2
    ON TAB2.OID = TAB2.SEC_ID
  CROSS JOIN TAB3;

请注意,NVL和COALESCE在几个方面略有不同,尽管这两者似乎都不是一个因素。首先,NVL总是需要两个参数,而COALESCE可以使用尽可能多的参数 - 它返回第一个非NULL参数。其次,NVL总是评估它的两个参数(例如,如果为NVL的一个或两个参数指定了一个函数,两个函数都被调用),而COALESCE只计算查找非NULL结果所需的许多参数。 ;因此,如果为COALESCE提供了两个参数函数,并且第一个返回非NULL值,则永远不会调用第二个函数。这里不是问题,但在其他情况下可能很重要(由于副作用)。

祝你好运。

© www.soinside.com 2019 - 2024. All rights reserved.