我是我的包裹,我列入了多个这样的工作:
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;
在所有作业完成之前,如何阻止我的代码?如果有更好的方法,有人可以给我一个例子吗?
答案 0 :(得分:2)
当有人发布了另一个StackOverflow答案的链接时,可以使用DBMS_SCHEDULER
中的链完成此操作。
答案 1 :(得分:1)
不幸的是,Oracle中的会话间通信不如OS中的进程间通信那么方便。但你可以
lock table ... in exclusive mode
在工作中并通过
执行等待工作的终止select ... for update
答案 2 :(得分:1)
如果您没有很多工作,可以使用DBMS_LOCK包创建自己的锁定对象。每个作业用一个众所周知的名称创建一个。让作业获得锁定,主作业等待释放所有锁定。
答案 3 :(得分:1)
DECLARE
cnt NUMBER:=1;
BEGIN
WHILE cnt>=1
LOOP
SELECT count(1) INTO cnt FROM dba_scheduler_running_jobs srj
WHERE srj.job_name IN ('TEST_JOB1','TEST_JOB2');
IF cnt>0 THEN
dbms_lock.sleep (5);
END IF;
END LOOP;
dbms_output.put_line('ASASA');
END;