5

次のように、他の多くの手順を実行するprocを含むパッケージがあります。

CREATE PACKAGE BODY pkg IS
    CREATE PROCEDURE do
    IS
    BEGIN
        other_pkg.other_proc;
        other_pkg2.other_proc2;
        other_pkg3.other_proc3;
    END;
END;

手順を順次ではなく並行して実行する方法はありますか?

編集:

DBMS_SCHEDULERこれは、このインスタンスで使用する適切な方法ですか:

CREATE PACKAGE BODY pkg IS
    CREATE PROCEDURE do
    IS
    BEGIN
        DBMS_SCHEDULER.CREATE_JOB('job_other_pkg.other_proc', 'STORED_PROCEDURE', 'other_pkg.other_proc;');
        DBMS_SCHEDULER.RUN_JOB('job_other_pkg.other_proc', FALSE);
        -- ...
    END;
END;
4

2 に答える 2

7

dbms_job(または) パッケージを使用してdbms_scheduler、並行して実行されるジョブを送信できます。を使用している場合dbms_job、ジョブの送信はトランザクションの一部になるため、トランザクションが完了するとジョブが開始されます。

CREATE PACKAGE BODY pkg IS
    CREATE PROCEDURE do
    IS
      l_jobno pls_integer;
    BEGIN
        dbms_job.submit(l_jobno, 'begin other_pkg.other_proc; end;' );
        dbms_job.submit(l_jobno, 'begin other_pkg2.other_proc2; end;' );
        dbms_job.submit(l_jobno, 'begin other_pkg3.other_proc3; end;' );
    END;
END;

を使用している場合dbms_scheduler、新しいジョブの作成はトランザクションではありません (つまり、新しいジョブを作成するたびに暗黙的なコミットが行われます)。このプロシージャが呼び出されるトランザクションで他の作業が行われている場合、トランザクションの整合性に問題が生じる可能性があります。一方、 を使用しdbms_schedulerている場合は、事前にジョブを作成し、単純にプロシージャから実行する方が簡単な場合があります (または、 を使用dbms_schedulerして、別のアクションまたはイベントに応答してジョブを実行するチェーンを作成します)。キュー上のメッセージ)。

もちろん、どちらのソリューションでも、これら 3 つのジョブの進行状況を監視するためのインフラストラクチャを構築する必要があります。ただし、ジョブがいつ成功するか (およびエラーが生成されるかどうか) を気にする必要があります。

使用する場合DBMS_SCHEDULER

  • 動的 SQL を使用する必要はありません。を捨てて、他のプロシージャと同じように、パッケージのプロシージャを直接EXECUTE IMMEDIATE呼び出すことができます。DBMS_SCHEDULER
  • を呼び出すときRUN_JOBは、2 番目のパラメーターを渡す必要があります。このuse_current_sessionパラメーターは、ジョブを現在のセッションで実行する (およびブロックする) か、別のセッションで実行するか (この場合、現在のセッションを続行して他のことを実行できる) を制御します。複数のジョブを並行して実行したいので、 の値を渡す必要がありますfalse
  • auto_drop必須ではありませんが、( falseに設定して) ジョブを一度作成し、手順から実行する方がより一般的です。

したがって、おそらくパッケージ外でジョブを作成したいと思うでしょう。そうすれば、手順は次のようになります

CREATE PACKAGE BODY pkg IS
    CREATE PROCEDURE do
    IS
    BEGIN
        DBMS_SCHEDULER.RUN_JOB('job_other_pkg.other_proc', false);
        DBMS_SCHEDULER.RUN_JOB('job_other_pkg2.other_proc2', false);
        DBMS_SCHEDULER.RUN_JOB('job_other_pkg3.other_proc3', false);
    END;
END;
于 2013-01-25T21:53:42.953 に答える
1

もう 1 つの解決策は、Oracle の SQL 並列処理メカニズムをハックすることです。How to execute a stored procedure in a different session in same time in pl/sql への回答を参照してください 。

これは、William Robertson の優れたソリューションであるParallel PL/SQL launcherを使用しています。

(でテスト済みOracle 10g)

于 2016-05-12T08:27:41.133 に答える