Oracleのジョブ・チェーンを使用して複数処理を1つのジョブに登録する方法
Oracle Database では Oracle Scheduler を使用してジョブを実行させることが可能ですが、このジョブをOSのバッチファイルやジョブ管理ツールを利用せず、「ジョブの結果に基づいて他のジョブを実行したい」というお問い合わせをいただくことがあります。
今回はジョブの結果に基づいて後続の処理を実行させる方法として、Oracle Database のジョブ・チェーン機能を紹介します。
ジョブ・チェーン機能
ジョブ・チェーン機能では複数のジョブを1つのスケジューラジョブとして動作させることが出来ます。また、ジョブの結果により、次に実行するジョブを変化させるような条件分岐を含むことも出来ます。
例えば以下の図はジョブAのメイン処理を実行させ、正常に完了した場合のみ後続処理のジョブB、ジョブCを実行するという処理です。メイン処理のジョブAが失敗した場合はリカバリ処理のジョブDを実行させ、リカバリ処理の成功、失敗により実行させるジョブを変化させるといったジョブ・チェーンとなります。
上記条件分岐の場合、ジョブ・チェーンの設定例としては以下の通り、作成するステップは6つで、ルールは10個で制御できます。
【ステップ】
|
DBMS_SCHEDULER.DEFINE_CHAIN_STEP('my_chain1', 'step1','JOB_A');
|
|
DBMS_SCHEDULER.DEFINE_CHAIN_STEP('my_chain1', 'step2','JOB_B');
|
|
DBMS_SCHEDULER.DEFINE_CHAIN_STEP('my_chain1', 'step3','JOB_C');
|
|
DBMS_SCHEDULER.DEFINE_CHAIN_STEP('my_chain1', 'step4','JOB_D');
|
|
DBMS_SCHEDULER.DEFINE_CHAIN_STEP('my_chain1', 'step5','JOB_E');
|
|
DBMS_SCHEDULER.DEFINE_CHAIN_STEP('my_chain1', 'step6','JOB_F');
|
【ルール】
①-- Step1(JOB_A)は必ず実行(condition=>'TRUE')
DBMS_SCHEDULER.DEFINE_CHAIN_RULE('my_chain1', 'TRUE', 'START step1');
②-- -- Step1(JOB_A)が正常に完了した場合、Step2(JOB_B)を実行
DBMS_SCHEDULER.DEFINE_CHAIN_RULE('my_chain1', 'Step1 SUCCEEDED','Start Step2');
③-- Step1(JOB_A)でエラーが発生した場合、Step4(JOB_D)を実行
DBMS_SCHEDULER.DEFINE_CHAIN_RULE('my_chain1', 'Step1 FAILED','START step4');
④-- Step2(JOB_B)が正常に完了した場合、Step3(JOB_C)を実行
DBMS_SCHEDULER.DEFINE_CHAIN_RULE('my_chain1', 'Step2 SUCCEEDED','Start Step3');
⑤-- Step2(JOB_B)でエラーが発生した場合、終了へ
DBMS_SCHEDULER.DEFINE_CHAIN_RULE('my_chain1', 'Step2 FAILED','END');
⑥-- Step3(JOB_C)は処理が完了次第(成功/失敗に関わらず)チェーンを終了
DBMS_SCHEDULER.DEFINE_CHAIN_RULE('my_chain1', 'step3 COMPLETED', 'END');
⑦-- Step4(JOB_D)が正常に完了した場合、Step5(JOB_E)を実行
DBMS_SCHEDULER.DEFINE_CHAIN_RULE('my_chain1', 'Step4 SUCCEEDED','Start Step5');
⑧-- Step4(JOB_D)でエラーが発生した場合、Step6(JOB_F)を実行
DBMS_SCHEDULER.DEFINE_CHAIN_RULE('my_chain1', 'Step4 FAILED','START step6');
⑨-- Step5(JOB_E)は処理が完了次第(成功/失敗に関わらず)チェーンを終了
DBMS_SCHEDULER.DEFINE_CHAIN_RULE('my_chain1', 'step5 COMPLETED', 'END');
⑩-- Step6(JOB_F)は処理が完了次第(成功/失敗に関わらず)チェーンを終了
DBMS_SCHEDULER.DEFINE_CHAIN_RULE('my_chain1', 'step6 COMPLETED', 'END');
|
ジョブ・チェーンの作成
以下サンプルは前のプログラムが正常完了した場合は次のプログラムを実行し、失敗した場合はその時点で終了させる ジョブ・チェーン の作成例です。
(1). ジョブ・チェーンで使用するプログラムを作成
SQL> BEGIN
2 DBMS_SCHEDULER.CREATE_PROGRAM(
3 program_name => 'TEST_PROGRAM1',
4 program_type => 'PLSQL_BLOCK',
5 program_action => 'BEGIN insert into test1 values(sysdate); END;',
6 enabled => TRUE,
7 comments => 'Program to insert using a PL/SQL block.');
8 DBMS_SCHEDULER.enable (name => 'TEST_PROGRAM1');
9 END;
10 /
PL/SQLプロシージャが正常に完了しました。
SQL> BEGIN
2 DBMS_SCHEDULER.CREATE_PROGRAM(
3 program_name => 'TEST_PROGRAM2',
4 program_type => 'PLSQL_BLOCK',
5 program_action => 'BEGIN insert into test2 values(sysdate); END;',
6 enabled => TRUE,
7 comments => 'Program to insert using a PL/SQL block.');
8 DBMS_SCHEDULER.enable (name => 'TEST_PROGRAM2');
9 END;
10 /
PL/SQLプロシージャが正常に完了しました。
SQL> BEGIN
2 DBMS_SCHEDULER.CREATE_PROGRAM(
3 program_name => 'TEST_PROGRAM3',
4 program_type => 'PLSQL_BLOCK',
5 program_action => 'BEGIN insert into test3 values(sysdate); END;',
6 enabled => TRUE,
7 comments => 'Program to insert using a PL/SQL block.');
8 DBMS_SCHEDULER.enable (name => 'TEST_PROGRAM3');
9 END;
10 /
PL/SQLプロシージャが正常に完了しました。
SQL> BEGIN
2 DBMS_SCHEDULER.CREATE_PROGRAM(
3 program_name => 'TEST_PROGRAM4',
4 program_type => 'PLSQL_BLOCK',
5 program_action => 'BEGIN insert into test4 values(sysdate); END;',
6 enabled => TRUE,
7 comments => 'Program to insert using a PL/SQL block.');
8 DBMS_SCHEDULER.enable (name => 'TEST_PROGRAM4');
9 END;
10 /
PL/SQLプロシージャが正常に完了しました。
(2). チェーンの作成
SQL> BEGIN
2 DBMS_SCHEDULER.CREATE_CHAIN (
3 chain_name => 'my_chain1',
4 rule_set_name => NULL,
5 evaluation_interval => NULL,
6 comments => NULL);
7 END;
8 /
PL/SQLプロシージャが正常に完了しました。
(3). チェーンにステップ(プログラム)を追加
SQL> BEGIN
2 DBMS_SCHEDULER.DEFINE_CHAIN_STEP('my_chain1', 'step1','TEST_PROGRAM1');
3 DBMS_SCHEDULER.DEFINE_CHAIN_STEP('my_chain1', 'step2','TEST_PROGRAM2');
4 DBMS_SCHEDULER.DEFINE_CHAIN_STEP('my_chain1', 'step3','TEST_PROGRAM3');
5 DBMS_SCHEDULER.DEFINE_CHAIN_STEP('my_chain1', 'step4','TEST_PROGRAM4');
6 END;
7 /
PL/SQLプロシージャが正常に完了しました。
(4). チェーンのルールを追加
【設定するルール】
①TEST_PROGRAM1を実行。
②TEST_PROGRAM1が成功していればTEST_PROGRAM2を実行。
失敗していればこれ以降のジョブは実行しない。
③TEST_PROGRAM2が成功していればTEST_PROGRAM3を実行。
失敗していればこれ以降のジョブは実行しない。
④TEST_PROGRAM3が成功していればTEST_PROGRAM4を実行。
失敗していればこのジョブは実行しない。
SQL> BEGIN
2 -- step1(TEST_PROGRAM1)は必ず実行(condition=>'TRUE')
3 DBMS_SCHEDULER.DEFINE_CHAIN_RULE('my_chain1', 'TRUE', 'START step1');
4 -- ステップでエラーが発生した場合、チェーンを終了
5 DBMS_SCHEDULER.DEFINE_CHAIN_RULE('my_chain1', 'Step1 FAILED','END');
6 DBMS_SCHEDULER.DEFINE_CHAIN_RULE('my_chain1', 'Step2 FAILED','END');
7 DBMS_SCHEDULER.DEFINE_CHAIN_RULE('my_chain1', 'Step3 FAILED','END');
8 -- ステップが正常に完了した場合、次のステップを実行
9 DBMS_SCHEDULER.DEFINE_CHAIN_RULE('my_chain1', 'Step1 SUCCEEDED','Start Step2');
10 DBMS_SCHEDULER.DEFINE_CHAIN_RULE('my_chain1', 'Step2 SUCCEEDED','Start Step3');
11 DBMS_SCHEDULER.DEFINE_CHAIN_RULE('my_chain1', 'Step3 SUCCEEDED','Start Step4');
12 -- step4(TEST_PROGRAM4)は処理が完了次第(成功/失敗に関わらず)チェーンを終了
13 DBMS_SCHEDULER.DEFINE_CHAIN_RULE('my_chain1', 'step4 COMPLETED', 'END');
14 END;
15 /
PL/SQLプロシージャが正常に完了しました。
【参考情報】
条件構文の詳細については、以下マニュアルをご参照ください。
データベース管理者ガイド 19c F16141-06(原本部品番号:E96348-08) 2020年7月
- 29.6.5 チェーンへのルールの追加
https://docs.oracle.com/cd/F19136_01/admin/scheduling-jobs-with-oracle-scheduler.html#GUID-5B924F0A-7E1A-4361-ADB4-F3F07CFC81EE
PL/SQLパッケージおよびタイプ・リファレンス 19c F16147-07(原本部品番号:E96430-11) 2020年5月
- 146.6.25 DEFINE_CHAIN_RULEプロシージャ
https://docs.oracle.com/cd/F19136_01/arpls/DBMS_SCHEDULER.html#GUID-BF7D99FE-C33F-444E-8725-BBC24DD33027
(5). チェーンの有効化
SQL> BEGIN
2 DBMS_SCHEDULER.ENABLE ('my_chain1');
3 END;
4 /
PL/SQLプロシージャが正常に完了しました。
(6). ジョブ・チェーンを実行
SQL> exec DBMS_SCHEDULER.RUN_CHAIN ('my_chain1','','test_my_chain1');
PL/SQLプロシージャが正常に完了しました。
以下のようなジョブ・チェーンのスケジュールも可能です。
SQL> begin
2 DBMS_SCHEDULER.CREATE_JOB (job_name=>'test_my_chain1',
3 job_type=>'CHAIN', job_action=>'my_chain1',
4 repeat_interval=>'freq=daily;byhour=23;byminute=0;bysecond=0',
5 enabled=>true);
6 end;
7 /
PL/SQLプロシージャが正常に完了しました。
【補足情報】
*1 実行中のジョブ・チェーンの状況は *_SCHEDULER_RUNNING_CHAINS の情報から確認出来ます。
SQL> select JOB_NAME,CHAIN_NAME,STEP_NAME,STATE,ERROR_CODE,COMPLETED
2 from USER_SCHEDULER_RUNNING_CHAINS order by STEP_NAME;
JOB_NAME CHAIN_NAME STEP_NAME STATE ERROR_CODE COMPL
----------------- -------------- ------------- -------------- -------------- -----------
TEST_MY_CHAIN1 MY_CHAIN1 STEP1 SUCCEEDED 0 TRUE
TEST_MY_CHAIN1 MY_CHAIN1 STEP2 SUCCEEDED 0 TRUE
TEST_MY_CHAIN1 MY_CHAIN1 STEP3 RUNNING FALSE
TEST_MY_CHAIN1 MY_CHAIN1 STEP4 NOT_STARTED FALSE
*2 ジョブの完了後は *_SCHEDULER_RUNNING_CHAINS の情報は確認出来ないため、実行後の履歴は *_SCHEDULER_JOB_RUN_DETAILS より確認可能です。
SQL> select JOB_NAME,JOB_SUBNAME,STATUS,ERROR#,ACTUAL_START_DATE
2 from USER_SCHEDULER_JOB_RUN_DETAILS order by ACTUAL_START_DATE;
JOB_NAME JOB_SUBNAM STATUS ERROR# ACTUAL_START_DATE
------------------ -------------- ------------ ------------- ----------------------------------
TEST_MY_CHAIN1 SUCCEEDED 0 21-02-06 00:50:17.824665 ASIA/TOKYO
TEST_MY_CHAIN1 STEP1 SUCCEEDED 0 21-02-06 00:50:17.950740 ASIA/TOKYO
TEST_MY_CHAIN1 STEP2 SUCCEEDED 0 21-02-06 00:50:18.064066 ASIA/TOKYO
TEST_MY_CHAIN1 STEP3 FAILED 6550 21-02-06 00:50:18.168103 ASIA/TOKYO
上記例では STEP3 で ORA-06550 のエラーを受けて失敗しています。エラーの詳細は同ディクショナリビューの ERRORS 列からも確認できます。
SQL> select JOB_NAME,JOB_SUBNAME,STATUS,ERROR#,ERRORS
2 from user_SCHEDULER_JOB_RUN_DETAILS WHERE ERROR# = '6550';
JOB_NAME JOB_SUBNAM STATUS ERROR# ERRORS
---------------- -------------- --------- ---------- -------------------------------------------------
TEST_MY_CHAIN1 STEP3 FAILED 6550 ORA-06550: 行1、列775:
PL/SQL: ORA-00942: 表またはビューが存在しません。
ORA-06550: 行1、列763:
PL/SQL: SQL Statement ignored
EMCC でのジョブ・チェーンの作成
ジョブ・チェーンは Enterprise Manager Cloud Control (以後 EMCC) でも作成可能です。
データベースの管理画面より、[管理]-[Oracle Scheduler]-[チェーン]の箇所より設定可能です。
実際の EMCC の画面では以下箇所からチェーンの設定を行います。
以下画面にて既存チェーンの編集や新規チェーンの作成などが実行出来ます。
上記画面の「作成」を選択すると以下のチェーンの作成画面が表示されますので以下のように任意のチェーン名やステップ、ルールなどを入力します。
引数を使用する場合
現行バージョンであるOracle Database 10.2~21cまでのバージョンでは、引数がサポートされておりません。
しかし実際に実行するジョブでは引数を含むジョブを実行させることが要件となっていることがあります。そのような場合には、引数を渡すシェルをジョブ・チェーンで実行するジョブと引数を必要とするジョブの間に作成することで対応出来ます。
実際の実行例は以下のとおりです。
(1). ジョブ・チェーンに組み込むシェルを実行するプログラムを作成
SQL> BEGIN
2 DBMS_SCHEDULER.CREATE_PROGRAM(
3 program_name => 'TEST_PROGRAM1',
4 program_type => 'EXECUTABLE',
5 program_action => '/home/oracle/work/TEST_PROGRAM1.sh',
6 enabled => TRUE);
7 DBMS_SCHEDULER.enable (name => 'TEST_PROGRAM1');
8 END;
9 /
PL/SQLプロシージャが正常に完了しました。
(2). (1)のプログラムで実行されるシェルには引数と実行するプログラムを指定します。
-- 以下シェルでは第一引数を S19000 で TEST_PROGRAM1_PLAY.sh を実行
$ cat /home/oracle/work/TEST_PROGRAM1.sh
/home/oracle/work/TEST_PROGRAM1_PLAY.sh S19000
(3). 引数が渡される処理例
-- 引数で渡された値を接続先情報として別SQLファイルを実行するシェル
$ cat /home/oracle/work/TEST_PROGRAM1_PLAY.sh
sqlplus -l OHBA/oracle@$1 @test.sql
-- SQLファイルの中身例
$ cat test.sql
-- SQL で ORA- エラーが発生した場合、ジョブを失敗させる為に
-- WHENEVER SQLERROR EXIT FAILURE ROLLBACK を指定
WHENEVER SQLERROR EXIT FAILURE ROLLBACK
insert into test1 values(sysdate);
commit;
exit
まとめ
今回はデータベースの標準機能であるジョブ・チェーン機能を紹介しました。本機能はバージョン 10.2以降であれば Standard Edition 、Enterprise Edition に関わらず使用可能な機能です。外部ツールに頼らないジョブスケジュール管理も可能になるため、簡易な定期ジョブや情報収集に本機能をご利用いただくのはいかがでしょうか。
■本記事の内容について
本記事に記載されている製品およびサービス、定義及び条件は、特段の記載のない限り本記事執筆時点のものであり、予告なく変更になる可能性があります。あらかじめご了承ください。
■商標に関して
・Oracle®、Java及びMySQLは、Oracle、その子会社及び関連会社の米国及びその他の国における登録商標です。
・Amazon Web Services、AWS、Powered by AWS ロゴ、[およびかかる資料で使用されるその他の AWS 商標] は、Amazon.com, Inc. またはその関連会社の商標です。
文中の社名、商品名等は各社の商標または登録商標である場合があります。
関連している記事
本記事では、従来のON COMMIT MViewが抱えてきたこのようなスループット低下や待機イベントのボトルネックを振り返りつつ、Oracle AI Database 26aiが提供する「同時リフレッシュ(Concurrent Refresh)」によって、OLTP/DWHそれぞれのユースケースでどのような改善が見込めるのかを検証していきます。
- Oracle Cloud
- Oracle Database
2026.03.25
BaseDBの運用でData Pump用の領域が不足した際、外部ストレージの活用が有効です。本記事では3つのストレージについて1TB利用時のコスト目安や性能、運用負荷を徹底比較します。自社環境に最適な外部ストレージ選びのポイントが分かります。
Oracle Trace File Analyzer(TFA)は、障害時のログ収集を効率化するツールです。複数ログの一括取得や時間指定、シングル環境での導入手順まで、現場目線でわかりやすく解説します。