Wie kann ich warten, bis alle meine Zeitplaner-Aufträge abgeschlossen haben?

Ich mir mein Paket, ich bin enqueueing mehrere jobs wie diese:

dbms_scheduler.create_job
  ( job_name     => p_job_name
  , job_type     => 'PLSQL_BLOCK'
  , job_action   => p_sql_code
  , start_date   => SYSDATE
  , enabled      => TRUE
  , comments     => 'Running batch jobs in parallel');

Habe ich einmal getan für so viele parallelen jobs, die ich wünschte zu beginnen, die ich brauche, um zu blockieren, bis alle Aufträge abgeschlossen haben.

Derzeit habe ich zu schlafen und Abfrage der Tabellen ALL_SCHEDULER_JOB_RUN_DETAILS und ALL_SCHEDULER_JOBS und überprüfen Sie den status des jobs. Es scheint wie eine wirklich hässliche Lösung. Hier ist die SQL, die ich benutze:

PROCEDURE run_jobs
  ( p_jobs    StringTableType
  , p_sql     VARCHAR2(4000) )
IS

  l_jobs         StringTableType;
  l_status       sys_type.STRING;
  l_additional_info  sys_type.text;
  l_done         BOOLEAN;
  i              PLS_INTEGER;

BEGIN

  l_jobs := p_jobs;

  -- Submit jobs
  FOR i IN 1..l_jobs.COUNT LOOP

  dbms_scheduler.create_job
    ( job_name     => l_jobs(i)
    , job_type     => 'PLSQL_BLOCK'
    , job_action   => p_sql
    , start_date   => SYSDATE
    , enabled      => TRUE
    , comments     => 'Running batch jobs in parallel');

  END LOOP;

  -- now wait untile all jobs are finished
  l_done := FALSE;

  WHILE NOT l_done LOOP

    DBMS_LOCK.sleep(5);

    l_done := TRUE;

    i := l_jobs.FIRST;
    WHILE i IS NOT NULL LOOP

      WITH jobs_log
           AS (SELECT job_name, state status, '' additional_info
                 FROM all_scheduler_jobs
               UNION
               SELECT job_name, status, additional_info
                 FROM all_scheduler_job_run_details
               )
      SELECT status, additional_info
        INTO l_status, l_additional_info
        FROM jobs_log
       WHERE job_name = p_jobs (i);

      --Analyze job status
      CASE
        WHEN l_status = 'RUNNING' THEN
          l_done := FALSE;

        WHEN l_status = 'SUCCEEDED' THEN
          l_jobs.DELETE(i);

        WHEN l_status = 'FAILED' THEN
          l_jobs.DELETE(i);

        ELSE
          l_done := FALSE;

      END CASE;

      i := l_jobs.NEXT(i);

    END LOOP;

  END LOOP;

END run_jobs;

Wie kann ich verhindern, mein code, bis alle jobs beendet haben? Kann jemand mir ein Beispiel, ob es einen besseren Weg, dies zu tun?

  • > Wie kann ich warten, bis alle meine Zeitplaner-Aufträge abgeschlossen haben? Nehmen Sie ein Nickerchen ;^)
  • Finden Sie diese Antwort auf eine ähnliche Frage, Adam Hawkes empfiehlt die Schaffung einer Kette via dbms_scheduler. Es sieht aus wie eine elegante Lösung.
  • eine große Ressource. Danke. Es ist das Problem behoben.
Schreibe einen Kommentar