简体   繁体   中英

Oracle PL SQL, Simplifying my procedure

I have a following procedure.

PROCEDURE PROC_SELECT_ORDERTBL(
   my_cursor OUT SYS_REFCURSOR,
   p_ORDER_ID IN VARCHAR2
   ...
)
BEGIN
    IF p_ORDER_ID IS NULL THEN
       OPEN my_cursor FOR
       [VERY LONG SELECT STATEMENT1]
    ELSE
       OPEN my_cursor FOR
       [VERY LONG SELECT STATEMENT2]
    END IF;

END PROC_SELECT_ORDERTBL

select statement 1 and 2 are almost same.

statement2 = statement1 + where clase(checking p_ORDER_ID)

I want to simplifying my procedure like next.

PROCEDURE PROC_SELECT_ORDERTBL(
   my_cursor OUT SYS_REFCURSOR,
   p_ORDER_ID IN VARCHAR2
   ...
)
BEGIN

    WITH viewData AS
    [VERY LONG SELECT STATEMENT1]

    IF p_ORDER_ID IS NULL THEN
       OPEN my_cursor FOR
       viewData
    ELSE
       OPEN my_cursor FOR
       viewData + where clause
    END IF;

END PROC_SELECT_ORDERTBL

But this doesn't compile.

----------------------This in my whole procedure code-------------------

  -- ORDERTBL 종이식권 주문단위로 조회
  PROCEDURE PROC_SELECT_ORDERTBL (
    my_cursor OUT SYS_REFCURSOR,  -- CURSOR
    p_AREA_ID IN VARCHAR2,    -- AREA_ID
    p_EQP_ID IN VARCHAR2,     -- EQP_ID
    p_ORDER_ID IN VARCHAR2,   -- ORDER_ID
    p_date_from IN VARCHAR2,  -- yymmdd 조회시작일
    p_date_to IN VARCHAR2,    -- yymmdd 조회종료일
    p_errorcode OUT NUMBER    -- error code
  ) AS
  BEGIN
    p_errorcode := 0;

    IF p_ORDER_ID IS NULL THEN
      OPEN my_cursor FOR
        SELECT ORD.ORDER_DATE AS 판매일자, ORD.ORDER_TIME AS 판매시간, ORD_ID.ORDER_ID AS 주문번호, TOTAL_SALES AS 판매금액
        FROM
        (
          --판매일자, 판매시간, 판매금액
          SELECT ORDER_DATE, ORDER_TIME, SUM(ORDER_FEE) AS TOTAL_SALES
          FROM 
          (
            SELECT DISTINCT ORDER_DATE, ORDER_TIME, ORDER_FEE FROM ORDERTBL 
            WHERE AREA_ID = p_AREA_ID AND EQP_ID = p_EQP_ID AND
            ORDER_DATE >= p_date_from AND ORDER_DATE <= p_date_to
          )
          GROUP BY ORDER_DATE, ORDER_TIME
        ) ORD
        JOIN 
        (
          --판매일자, 판매시간, 주문번호
          SELECT ORDER_DATE, ORDER_TIME, MIN(ORDER_ID) AS ORDER_ID
          FROM ORDERTBL
          WHERE AREA_ID = p_AREA_ID AND EQP_ID = p_EQP_ID AND
          ORDER_DATE >= p_date_from AND ORDER_DATE <= p_date_to
          GROUP BY ORDER_DATE, ORDER_TIME
        ) ORD_ID
        ON ORD.ORDER_DATE = ORD_ID.ORDER_DATE AND ORD.ORDER_TIME = ORD_ID.ORDER_TIME
        ORDER BY ORD.ORDER_DATE, ORD.ORDER_TIME;
    ELSE
    OPEN my_cursor FOR
      SELECT ORD.ORDER_DATE AS 판매일자, ORD.ORDER_TIME AS 판매시간, ORD_ID.ORDER_ID AS 주문번호, TOTAL_SALES AS 판매금액
      FROM
      (
        --판매일자, 판매시간, 판매금액
        SELECT ORDER_DATE, ORDER_TIME, SUM(ORDER_FEE) AS TOTAL_SALES
        FROM 
        (
          SELECT DISTINCT ORDER_DATE, ORDER_TIME, ORDER_FEE FROM ORDERTBL 
          WHERE AREA_ID = p_AREA_ID AND EQP_ID = p_EQP_ID AND
          ORDER_DATE >= p_date_from AND ORDER_DATE <= p_date_to
        )
        GROUP BY ORDER_DATE, ORDER_TIME
      ) ORD
      JOIN 
      (
        --판매일자, 판매시간, 주문번호
        SELECT ORDER_DATE, ORDER_TIME, MIN(ORDER_ID) AS ORDER_ID
        FROM ORDERTBL
        WHERE AREA_ID = p_AREA_ID AND EQP_ID = p_EQP_ID AND
        ORDER_DATE >= p_date_from AND ORDER_DATE <= p_date_to
        GROUP BY ORDER_DATE, ORDER_TIME
      ) ORD_ID
      ON ORD.ORDER_DATE = ORD_ID.ORDER_DATE AND ORD.ORDER_TIME = ORD_ID.ORDER_TIME
      WHERE ORD_ID.ORDER_ID = p_ORDER_ID;
    END IF;

  EXCEPTION
    WHEN OTHERS THEN
      p_errorcode := SQLCODE;
  END PROC_SELECT_ORDERTBL;

You can use CASE construct in the where clause. The logic would be similar to your IF-ELSE condition. But, it is not a good coding practice.

I would go with NVL and DECODE .

Update : The DECODE and NVL parameter values depends on the column data type.

If P_ORDER_ID is NUMBER then use :

WHERE DECODE(p_order_id, NULL, 0, ORD_ID.ORDER_ID) = NVL(p_ORDER_ID, 0)

else if P_ORDER_ID is VARCHAR2 then use :

WHERE DECODE(p_order_id, NULL, '0', ORD_ID.ORDER_ID) = NVL(p_ORDER_ID, '0')

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM