특정 작업(쿼리 및 프로시저 실행)을 주기적으로 수행해야 하는 경우가 있다.
현재 진행 중인 업무를 예로 들어보자면 거래처로부터 몇 초에 한 번씩 오더 데이터를 받아와서 내부 DB에 MERGE하는 작업이 필요하다.
개발자가 정해진 스케줄에 따라 이를 직접 수행하는 것은 큰 부담이 따르므로 해당 작업을 대신해줄 대상이 필요하다.
이 때 활용할 수 있는 것이 ORACLE의 DBMS_JOB 패키지이다.
사용자는 주기적으로 수행해야 하는 작업을 JOB으로 등록(SUBMIT)한다.
등록된 JOB은 JOB_QUEUE에 추가되고, JOB_QUEUE_PROCESS가 QUEUE에 포함된 JOB들을 수행하는 역할을 한다.
JOB_QUEUE에 등록된 JOB들은 다음의 쿼리로 확인해 볼 수 있다.
SELECT *
FROM USER_JOBS;
DBMS_JOBS 패키지를 사용하기 위한 패키지의 프로시저는 다음과 같다.
대표적으로 사용되는 프로시저의 쓰임을 알아보자.
종류 | 설명 |
---|---|
SUBMIT | Job Queue에 Job 등록 |
REMOVE | Job Queue로부터 Job 제거 |
CHANGE | Job Queue의 Job 변경 |
NEXT_DATE | Job의 다음 수행시간 변경 |
INTERVAL | Job 수행주기 변경 |
WHAT | Job으로 등록된 프로시저 및 패키지 변경 |
RUN | Job 수동으로 강제 수행 |
예시
DECLARE
X NUMBER;
BEGIN
SYS.DBMS_JOB.SUBMIT(
JOB => X, -- 작업번호
WHAT => 'SERVER001.PK_TEST_001.PR_RECVORD_TEST;', -- 실행할 프로시저
NEXT_DATE => TRUNC(SYSDATE+1)+18/24, -- 다음 작업 시간
INTERVAL => 'SYSDATE+1/24/60/10', -- 실행 주기
NO_PARSE => FALSE -- 실행시 파싱 여부
);
END;
파라미터
JOB
: JOB QUEUE에 등록된 작업 번호, 자동으로 생성됨WHAT
: 실행 대상, 쿼리나 프로시저로 세미콜론(;)으로 끝나야 함NEXT_DATE
: 다음 작업이 실행될 시간, default는 SYSDATEINTERVAL
: 실행 주기, 초 단위까지 지정 가능, default는 NULLNO_PARSE
: 실행시 파싱 여부cf. OUT 매개변수가 있는 프로시저를 JOB으로 등록하는 경우
프로시저에 OUT 매개변수가 있는 경우 아래의 예시와 같이 'DECLARE ~ END'절을 이용하여 WHAT을 정의해야 한다.
DECLARE
X NUMBER;
BEGIN
SYS.DBMS_JOB.SUBMIT(
JOB => X, -- 작업번호
WHAT => 'DECLARE
OUT1 VARCHAR2(100);
OUT2 VARCHAR2(100);
BEGIN
SERVER001.PK_TEST_001.PR_RECVORD_TEST(OUT1,OUT2);
END;', -- 수행할 쿼리
NEXT_DATE => TRUNC(SYSDATE+1)+18/24, -- 다음 작업 시간
INTERVAL => 'SYSDATE+1/24/60/10', -- 실행 주기
NO_PARSE => FALSE -- 실행시 파싱 여부
);
END;
작업 번호를 매개변수로 넣어 REMOVE 프로시저를 호출한다.
CALL DBMS_JOB.REMOVE(7828020);
작업번호와 변경 후 값을 매개변수로 넣어 프로시저를 호출한다.
-- 수행작업 변경
CALL DBMS_JOB.WHAT(43414,'TEST_PROCEDURE_002');
-- 수행간격 변경
CALL DBMS_JOB.INTERVAL(43414,'SYSDATE+1/24/60');
-- 다음 작업 시점 변경
CALL DBMS_JOB.NEXT_DATE(43414,TRUNC(SYSDATE+1)+7/24);
작업번호를 매개변수로 넣어 BROKEN 프로시저를 호출한다.
CALL DBMS_JOB.BROKEN(7828020,TRUE);
References