Converting a nested decode into equivalent CASE statement (needed for conversion from Oracle to PostgreSQL)

若如初见. 提交于 2020-06-17 13:17:09

问题


I am on Oracle 11.2.0.4. I have a nested DECODE statement that I need to convert into CASE statement. Can someone help on it. I am not sure of how it is done and in fact I don't fully understand the logic of it. If someone can explain what it basically intends to do and what would be the rewritten function using CASE that is Very useful to me. Here is the function...(note: do not worry about table joins , there are 3 tables and one condition etc. please focus on the DECODE and its conversion to CASE). Also I must manually convert and tools are not an option.

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;

回答1:


That would be something like this:

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 ...

Note that your FROM clause contains 3 tables, but WHERE joins just two of them. What about tab3? Also, consider switching to ANSI join.




回答2:


something like this :

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 is replaced by COALESCE

DECODE(a,b,c,d,e,...,f) is replaced by :

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

your last decode ( DECODE (tab1.co_id, NULL, tab2.oid, tab1.co_id), 1, 0))) is in fact an NVL( tab1.co_id,tab2.oid)




回答3:


The following should do what you want:

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;

Note that NVL and COALESCE are slightly different in a couple of respects, although neither seems to be a factor here. First, NVL always takes two arguments, while COALESCE can take as many as you care to supply - it returns the first non-NULL argument. Second, NVL always evaluates both of its arguments (e.g. if a function is specified for one or both of the arguments to NVL, both functions are called), while COALESCE only evaluates as many of the arguments are necessary to find a non-NULL result; thus, if COALESCE is given two functions for arguments and the first returns a non-NULL value, the second function is never called. Not an issue here, but perhaps important (due to side effects) in other cases.

Best of luck.



来源:https://stackoverflow.com/questions/52165727/converting-a-nested-decode-into-equivalent-case-statement-needed-for-conversion

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!