안녕하십니까.
패키지 만드는 중 하나 질문 드립니다.
커서 를 선언하지 않고 MERGE INTO 쿼리문을 사용해 그대로 데이터를 때려박았습니다.
오류가 없으면 JOB로그를 남기고 있으면 ERR로그를 남기는 그런 패키지 인데,
제가 알고 싶은 부분은
MERGE INTO OG_ODS_ORDER_SUMMARY_LJJ T -- OG_ODS_ORDER_SUMMARY_LJJ 에 데이터 적재
USING (SELECT A.YEAR
, A.MONTH
, SHOP_CODE
, SHOP_NAME
, A.TOT_AMT
, A.PLAN_AMT
, ABS((A.TOT_AMT - A.PLAN_AMT)) AS DIFF_AMT
, DECODE(A.PLAN_AMT,0,0,((A.TOT_AMT / A.PLAN_AMT) * 100)) AS DIFF_RATE
, CREATER
, CREAT_TIME
FROM (SELECT A.YEAR
, A.MONTH
, A.SHOP AS SHOP_CODE
, A.NAME AS SHOP_NAME
, A.TOT_AMT
, NVL( (SELECT SUM(PL_AMT) FROM OG_ODS_PLAN_BY_MAEJANG_LJJ WHERE YEAR(+) = A.YEAR AND MONTH(+) = A.MONTH AND SHOP(+) = A.SHOP ), 0 ) AS PLAN_AMT
, CREATER
, CREAT_TIME
FROM (SELECT /*+ INDEX( A OG_ODS_ORDER_AGGREGATION_PK ) */ A.YEAR
, A.MONTH
, A.SHOP
, (SELECT NAME FROM OG_MST_SHOP_LJJ WHERE SHOP = A.SHOP ) AS NAME
, SUM(A.TOT_AMT) AS TOT_AMT
, 'LJJ' AS CREATER
, SYSDATE AS CREAT_TIME
FROM OG_ODS_ORDER_AGGREGATION_LJJ A
WHERE BASE_DATE BETWEEN IN_FROM_DATE AND IN_TO_DATE
GROUP BY A.YEAR, A.MONTH , A.SHOP
) A
)A
) F
ON ( F.YEAR = T.YEAR AND F.MONTH = T.MONTH AND F.SHOP_CODE = T.SHOP_CODE )
WHEN MATCHED THEN -- 값이 존재하면 UPDATE
UPDATE SET T.SHOP_NAME = F.SHOP_NAME
, T.TOT_AMT = F.TOT_AMT
, T.PLAN_AMT = F.PLAN_AMT
, T.DIFF_AMT = F.DIFF_AMT
, T.DIFF_RATE = F.DIFF_RATE
, T.CREATER = F.CREATER
, T.CREAT_TIME = F.CREAT_TIME
WHEN NOT MATCHED THEN -- 값이 존재하지 않으면 INSERT
INSERT ( T.YEAR
, T.MONTH
, T.SHOP_CODE
, T.SHOP_NAME
, T.TOT_AMT
, T.PLAN_AMT
, T.DIFF_AMT
, T.DIFF_RATE
, T.CREATER
, T.CREAT_TIME
)
VALUES ( F.YEAR
, F.MONTH
, F.SHOP_CODE
, F.SHOP_NAME
, F.TOT_AMT
, F.PLAN_AMT
, F.DIFF_AMT
, F.DIFF_RATE
, F.CREATER
, F.CREAT_TIME
);
s_YEAR := F.YEAR -- YEAR
s_MONTH := F.MONTH --MONTH
DBMS_OUTPUT.PUT_LINE(v_YEAR||v_MONTH);
d_ETIME := SYSDATE; -- 작업종료시간 저장
EXCEPTION
WHEN OTHERS THEN
n_ERCODE := SQLCODE; -- 에러코드 변수에 저장
v_ERMSG := SQLERRM; -- 에러메시지 변수에 저장
DBMS_OUTPUT.PUT_LINE('JOB_LOG 에러코드:' || n_ERCODE || ' 에러메시지:' || v_ERMSG || ' 성공실패여부:' || v_YN);
END;
IF TO_CHAR(n_ERCODE) = '0' OR
TO_CHAR(n_ERCODE) IS NULL THEN
v_YN := 'Y'; -- 에러발생 X
ELSE
v_YN := 'N';
ROLLBACK;
GOTO JUMP; -- 에러발생 (RATE 적재 하지않고 바로 JOB과 ERR_JOB에 기록
END IF;
SAVEPOINT MERGE_RATE;
밑 줄 친 부분처럼 저렇게 적용은 되지 않더군요, JOB로그에 일일히 찍고 싶으나, 한번에 데이터가 들어가서 일일히는 안될 것 같고 마지막 ROW의 YEAR, MONTH 값이라도 찍고 싶은데, 두줄을 제외하고 패키지를실행하면 위에서 정의한 변수 초기화 부분 YEAR := NULL 로 들어가서 NOTNULL 제약조건에 걸려 에러가 발생합니다.
커서를 사용하지 않고, MERGE INTO 을 사용했을 경우, DATA를 변수로 받아서 OUT파라미터로 내보낼수 있을까요.
답변 부탁드립니다.
감사합니다.
-- 참고하시라고 총 패키지 쿼리 도 첨부해뒀습니다.