Oracle PL SQL,简化我的程序

时间:2014-09-22 02:32:12

标签: sql oracle stored-procedures

我有以下程序。

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语句1和2几乎相同。

statement2 = statement1 + where clase(check p_ORDER_ID)

我想简化下一步的程序。

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

但这不会编译。

----------------------这在我的整个程序代码-------------------

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

1 个答案:

答案 0 :(得分:0)

您可以在where子句中使用CASE构造。逻辑类似于您的IF-ELSE条件。但是,这不是一个好的编码实践。

我会选择NVLDECODE

更新:DECODE和NVL参数值取决于列数据类型。

如果P_ORDER_IDNUMBER,请使用:

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

如果P_ORDER_IDVARCHAR2,则使用:

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