APEX_PLSQL_JOBパッケージを使用すると、アプリケーションのバックグラウンドでPL/SQLコードを実行できます。操作が完了していない状態でもユーザーがアプリケーションで作業を継続できるため、長時間実行操作の管理に有効な方法です。
トピック:
APEX_PLSQL_JOBは、Oracle Databaseで提供されるDBMS_JOB機能をラップしたラッパー・パッケージです。APEX_PLSQL_JOBパッケージでは、PL/SQLをバックグラウンドで実行するために必要な機能のみが公開されることに注意してください。
表17-1に、APEX_PLSQL_JOBパッケージで使用可能なファンクションを示します。
表 17-1 APEX_PLSQL_JOBパッケージ: 使用可能なファンクション
| ファンクションまたはプロシージャ | 説明 |
|---|---|
|
|
このプロシージャを使用すると、バックグラウンドPL/SQLを送信できます。このプロシージャは、一意のジョブ番号を戻します。このジョブ番号は、このパッケージ内の他のプロシージャおよびファンクションの参照点として使用できるため、自分のスキーマ内に格納しておくと役に立ちます。 |
|
|
このプロシージャをコールすると、現在実行しているジョブのステータスを更新できます。このプロシージャは、送信されたPL/SQLからコールされたときに最も有効です。 |
|
|
このファンクションを使用すると、ジョブが送信されてから経過した時間を確認できます。 |
|
|
このファンクションをコールすると、そのデータベースが現在、 |
|
|
このプロシージャをコールすると、送信されたジョブをクリーンアップできます。送信されたジョブは、Oracle Application Expressによってそれらのレコードがクリーンアップされるか、または |
APEX_PLSQL_JOBパッケージに送信したすべてのジョブは、APEX_PLSQL_JOBSビューで表示できます。
このファンクションをコールすると、そのデータベースが現在、APEX_PLSQL_JOBパッケージへのジョブの送信をサポートするモードであるかどうかを確認できます。
構文
APEX_PLSQL_JOB.JOBS_ARE_ENABLED RETURN BOOLEAN;
パラメータ
なし。
例
次の例に、JOBS_ARE_ENABLEDファンクションを使用する方法を示します。この例では、このファンクションによってTRUEが戻された場合、「Jobs are enabled on this database instance」というメッセージが表示されます。そうでない場合は、「Jobs are not enabled on this database instance」というメッセージが表示されます。
BEGIN
IF APEX_PLSQL_JOB.JOBS_ARE_ENABLED THEN
HTP.P('Jobs are enabled on this database instance.');
ELSE
HTP.P('Jobs are not enabled on this database instance.');
END IF;
END;
このプロシージャをコールすると、送信されたジョブをクリーンアップできます。送信されたジョブは、Oracle Application Expressによってそれらのレコードがクリーンアップされるか、またはPURGE_PROCESSのコールによって手動で削除するまで、APEX_PLSQL_JOBSビューに保持されます。
構文
APEX_PLSQL_JOB.PURGE_PROCESS (
p_job IN NUMBER);
パラメータ
表17-2では、PURGE_PROCESSプロシージャで使用可能なパラメータについて説明します。
例
次の例に、PURGE_PROCESSプロシージャを使用して、ジョブ番号161で識別される送信済ジョブをパージする方法を示します。また、APEX_PLSQL_JOBSビューを参照して、すべての送信済ジョブをパージするか、または一部の送信済ジョブをパージすることができます。
BEGIN
APEX_PLSQL_JOB.PURGE_PROCESS(
p_job => 161);
END;
このファンクションを使用すると、バックグラウンドPL/SQLを送信できます。このファンクションは、一意のジョブ番号を戻します。このジョブ番号は、このパッケージ内の他のプロシージャおよびファンクションの参照点として使用できるため、自分のスキーマ内に格納しておくと役に立ちます。
構文
APEX_PLSQL_JOB.SUBMIT_PROCESS (
p_sql IN VARCHAR2,
p_when IN DATE DEFAULT SYSDATE,
p_status IN VARCHAR2 DEFAULT 'PENDING')
RETURN NUMBER;
パラメータ
表17-3に、SUBMIT_PROCESSファンクションで使用可能なパラメータを示します。
表17-3 SUBMIT_PROCESSのパラメータ
| パラメータ | 説明 |
|---|---|
|
|
ジョブで実行するプロセス。このプロセスには、任意の有効な無名ブロックを指定できます。次に例を示します。 'BEGIN <your code> END;' or 'DECLARE <your declaration> BEGIN <your code> END;' |
|
p_when |
実行のタイミング。デフォルトはSYSDATEで、ジョブはすぐに実行されます。後で実行されるようにジョブを設定することもできます。次に例を示します。
|
|
p_status |
このジョブのプレーン・テキストのステータス情報。 |
例
次の例に、SUBMIT_PROCESSファンクションを使用して、すぐに開始するバックグラウンド・プロセスを送信する方法を示します。
DECLARE
l_sql VARCHAR2(4000);
l_job NUMBER;
BEGIN
l_sql := 'BEGIN MY_PACKAGE.MY_PROCESS; END;';
l_job := APEX_PLSQL_JOB.SUBMIT_PROCESS(
p_sql => l_sql,
p_status => 'Background process submitted');
--store l_job for later reference
END;
このファンクションを使用すると、ジョブが送信されてから経過した時間を確認できます。
構文
APEX_PLSQL_JOB.TIME_ELAPSED(
p_job IN NUMBER)
RETURN NUMBER;
パラメータ
表17-4では、TIME_ELAPSEDファンクションで使用可能なパラメータについて説明します。
例
次の例に、TIME_ELAPSEDファンクションを使用して、ジョブ番号161で識別される送信済ジョブの経過時間を取得する方法を示します。
DECLARE
l_time NUMBER;
BEGIN
l_time := APEX_PLSQL_JOB.TIME_ELAPSED(p_job => 161);
END;
このプロシージャをコールすると、現在実行しているジョブのステータスを更新できます。このプロシージャは、送信されたPL/SQLからコールされたときに最も有効です。
構文
APEX_PLSQL_JOB.UPDATE_JOB_STATUS (
p_job IN NUMBER,
p_status IN VARCHAR2);
パラメータ
表17-5では、UPDATE_JOB_STATUSプロシージャで使用可能なパラメータについて説明します。
表17-5 UPDATE_JOB_STATUSのパラメータ
| パラメータ | 説明 |
|---|---|
|
|
ステータスを更新するジョブのジョブID。 |
|
p_status |
ジョブの現在のステータスとして使用される最大100文字の文字列。 |
例
次の例に、UPDATE_JOB_STATUSプロシージャを使用する方法を示します。この例では、次のことに注意してください。
002から010行では、100個のレコードをemp表に挿入するループを実行します。
APP_JOBは、INSERTのVALUES句内でバインド変数として参照され、UPDATE_JOB_STATUSへのコール内でp_jobパラメータの値として指定されます。
APP_JOBは、APEX_PLSQL_JOBに送信される際に、このプロセスに割り当てられるジョブ番号を表します。プロセス・コード内にこの予約アイテムを指定すると、実行時に実際のジョブ番号に置換されます。
この例では、コード・ブロック内で、10個のレコードごとにUPDATE_JOB_STATUSがコールされることに注意してください。通常、Oracleトランザクション規則では、コード・ブロック内で実行された更新は、トランザクション全体がコミットされるまで表示されません。一方、APEX_PLSQL_JOB.UPDATE_JOB_STATUSプロシージャは、ジョブが成功したか失敗したかにかかわらず更新を実行するように実装されています。このことは、次の2つの理由から重要です。
ステータスが「100 rows inserted」の場合でも、操作全体が成功したわけではありません。コード・ブロックでコミットが試行されたときにエラーが発生した場合、ステータスの更新は個別にコミットされるため、APEX_PLSQL_JOBSのuser_status列は影響を受けません。
更新は自律的に実行されます。ジョブが完了する前にジョブ・ステータスを表示できます。これによって、バックグラウンドで実行中の各操作についてステータス・テキストを表示できます。
BEGIN
FOR i IN 1 .. 100 LOOP
INSERT INTO emp(a,b) VALUES (:APP_JOB,i);
IF MOD(i,10) = 0 THEN
APEX_PLSQL_JOB.UPDATE_JOB_STATUS(
P_JOB => :APP_JOB,
P_STATUS => i || ' rows inserted');
END IF;
APEX_UTIL.PAUSE(2);
END LOOP;
END;