더북(TheBook)

그럼 CH17_SRC_TEST_PKG.SALES_DETAIL_PRC 프로시저에 로그를 쌓는 루틴을 추가해 보자.

입력

    CREATE OR REPLACE PACKAGE BODY ch17_src_test_pkg IS

      PROCEDURE sales_detail_prc ( ps_month IN VARCHAR2,
                                   pn_amt   IN NUMBER,
                                   pn_rate  IN NUMBER   )
    IS
      vn_total_time NUMBER := 0;     -- 소요시간 계산용 변수

      vn_log_id     NUMBER;          -- 로그 아이디
      vs_parameters VARCHAR2(500);   -- 매개변수
      vs_prg_log    VARCHAR2(2000);  -- 로그내용
    BEGIN
      -- 매개변수와 그 값을 가져온다
      vs_parameters := 'ps_month => ' || ps_month || ', pn_amt => ' || pn_amt || ' , pn_rate => ' || pn_rate;

    BEGIN
      -- 로그 아이디 값 생성
      vn_log_id := prg_log_seq.NEXTVAL;
      -- 로그 테이블에 데이터 생성
      INSERT INTO program_log (
                                log_id,
                                program_name,
                                parameters,
                                state,
                                start_time )
      VALUES ( vn_log_id,
             'ch17_src_test_pkg.sales_detail_prc',
                vs_parameters,
             'Running',
                SYSTIMESTAMP);

      COMMIT;
      END;

      --1. p_month에 해당하는 월의 CH17_SALES_DETAIL 데이터 삭제
      vn_total_time := DBMS_UTILITY.GET_TIME;

      DELETE ch17_SALES_DETAIL
      WHERE sales_month = ps_month;

      -- DELETE 소요 시간 계산(초로 계산하기 위해 100으로 나눈다)
      vn_total_time := (DBMS_UTILITY.GET_TIME - vn_total_time) / 100;

      -- DELETE 로그 내용 만들기
      vs_prg_log :=  'DELETE 건수 : ' || SQL%ROWCOUNT || ' , 소요시간: ' || vn_total_time || CHR(13);

      --2. p_month에 해당하는 월의 CH17_SALES_DETAIL 데이터 생성
      vn_total_time := DBMS_UTILITY.GET_TIME;

      INSERT INTO ch17_SALES_DETAIL
      SELECT b.prod_name,
             d.channel_desc,
             c.cust_name,
             e.emp_name,
             a.sales_date,
             a.sales_month,
             sum(a.quantity_sold),
             sum(a.amount_sold)
        FROM sales a,
             products b,
             customers c,
             channels d,
             employees e
      WHERE a.sales_month = ps_month
        AND a.prod_id     = b.prod_id
        AND a.cust_id     = c.cust_id
        AND a.channel_id  = d.channel_id
        AND a.employee_id = e.employee_id
      GROUP BY b.prod_name,
               d.channel_desc,
               c.cust_name,
               e.emp_name,
               a.sales_date,
               a.sales_month;

      -- INSERT 소요 시간 계산(초로 계산하기 위해 100으로 나눈다)
      vn_total_time := (DBMS_UTILITY.GET_TIME - vn_total_time)  / 100;

      -- INSERT 로그 내용 만들기
      vs_prg_log :=  vs_prg_log || 'INSERT 건수 : ' || SQL%ROWCOUNT || ' , 소요시간: ' || vn_total_time || CHR(13);

      -- 3. 판매금액(sales_amt)이 pn_amt보다 큰 건은 pn_rate 비율만큼 할인
      vn_total_time := DBMS_UTILITY.GET_TIME;

      UPDATE ch17_SALES_DETAIL
         SET sales_amt = sales_amt - ( sales_amt * pn_rate * 0.01)
       WHERE sales_month = ps_month
         AND sales_amt   > pn_amt;

      -- UPDATE 소요 시간 계산(초로 계산하기 위해 100으로 나눈다)
      vn_total_time := (DBMS_UTILITY.GET_TIME - vn_total_time)  / 100;

      -- UPDATE 로그 내용 만들기
      vs_prg_log :=  vs_prg_log || 'UPDATE 건수 : ' || SQL%ROWCOUNT || ' , 소요시간: ' || vn_total_time || CHR(13);

      COMMIT;

      BEGIN
        -- 로그 종료
        UPDATE program_log
           SET state = 'Completed',
               end_time = SYSTIMESTAMP,
               log_desc = vs_prg_log || '작업종료!'
         WHERE log_id = vn_log_id;

        COMMIT;
      END;

      EXCEPTION WHEN OTHERS THEN
        BEGIN
          vs_prg_log := SQLERRM;
          -- 오류 로그
          UPDATE program_log
             SET state = 'Error',
                 end_time = SYSTIMESTAMP,
                 log_desc = vs_prg_log
           WHERE log_id = vn_log_id;

          COMMIT;
        END;
        ROLLBACK;

      END sales_detail_prc;
    END ch17_src_test_pkg;

결과

    PACKAGE BODY CH17_SRC_TEST_PKG이(가) 컴파일되었습니다.
신간 소식 구독하기
뉴스레터에 가입하시고 이메일로 신간 소식을 받아 보세요.