我我的包,我入队多个作业是这样的:如何等待所有调度程序作业完成?
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');
一旦我这样做了,我想开始尽可能多的并行作业,我需要阻塞,直到所有的工作都有完成。
目前我不得不睡觉和轮询表ALL_SCHEDULER_JOB_RUN_DETAILS
和ALL_SCHEDULER_JOBS
并检查作业的状态。这似乎是一个非常难看的解决方案。这里是我使用的SQL:
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;
如何才能阻止我的代码,直到所有的工作完成?任何人都可以给我一个例子,如果有更好的方法来做到这一点?
>我怎么能等到我所有的调度工作已经完成? 打个盹; ^) – 2013-03-08 14:35:45
看到这个[回答相似的问题](http://stackoverflow.com/a/4600487/119634),亚当霍克斯建议通过dbms_scheduler创建一个链。它看起来像一个优雅的解决方案 – 2013-03-08 14:52:59
@VincentMalgrat,一个很好的资源。谢谢。它解决了这个问题。 – 2013-11-27 15:06:02