并行执行oracle PL / SQL

时间:2016-09-15 15:00:40

标签: oracle plsql parallel-processing package

基本上我在oracle 11g中有一个包处理文件并在多个表中验证和插入信息,     实现这一点我创建了一个存储过程,读取文件并传播信息,然后我调用多个存储过程     验证并在每个表中插入数据(每个表一个程序),对于每个SP在一个公共错误表中插入记录的错误,最后,     我调用最后一个存储过程来识别公共错误表中是否存在错误并生成包含这些错误的文件。

现在......我正在尝试改进代码以最小化执行时间,然后我实现每个验证和插入信息的SP     进入表不依赖于其他SP信息,所以我问是否有办法并行调用所有这些SP。

TODAY

STORED PROCEDURE charge_file
STORED PROCEDURE insert_table1
STORED PROCEDURE insert_table2
STORED PROCEDURE insert_table3 ...
STORED PROCEDURE return_file

我想做什么

STORED PROCEDURE charge_file
STORED PROCEDURE insert_table1 - STORED PROCEDURE insert_table2 - STORED PROCEDURE insert_table3 ...
STORED PROCEDURE return_file

3 个答案:

答案 0 :(得分:2)

使用parallel_execute作为示例:

create table proc_map (proc_id number, proc_name varchar2(64), is_active varchar2(1));

insert into proc_map (proc_id, proc_name, is_active) values (1, 'insert_table1', 'Y');
insert into proc_map (proc_id, proc_name, is_active) values (2, 'insert_table2', 'Y');
insert into proc_map (proc_id, proc_name, is_active) values (3, 'insert_table3', 'Y');


create or replace procedure p_run_proc (ip_start in number, ip_end in number)  is
  v_proc_name proc_map.proc_name%type;
begin
  begin
    select t.proc_name into v_proc_name 
    from proc_map t
    where t.proc_id = ip_start;
  exception
    when no_data_found then null;
    when too_many_rows then null;
  end;

  if v_proc_name is not null
    then
      execute immediate 'begin ' || v_proc_name || '; end;';
  end if;
end;

declare
  v_task_name varchar2(4000) := dbms_parallel_execute.generate_task_name;
  v_sql varchar2(4000);
  v_run varchar2(4000);
  v_thread_count number;
  v_task_status number;
begin
  dbms_parallel_execute.create_task (task_name => v_task_name);

  v_sql := 'select t.proc_id as num_col 
                  ,t.proc_id as num_col
            from proc_map t 
            where t.is_active = ''Y'' 
            order by t.proc_id';

  dbms_parallel_execute.create_chunks_by_SQL (task_name => v_task_name, sql_stmt => v_sql, by_rowid => false);

  v_run := 'begin p_run_proc (ip_start => :start_id, ip_end => :end_id); end;';

  select count(*) into v_thread_count 
  from proc_map t
  where t.is_active = 'Y';

  dbms_parallel_execute.run_task (task_name => v_task_name
                                 ,sql_stmt => v_run
                                 ,language_flag => dbms_sql.native
                                 ,parallel_level => v_thread_count);

  v_task_status := dbms_parallel_execute.task_status (task_name => v_task_name);

  if v_task_status = dbms_parallel_execute.FINISHED
    then
      dbms_parallel_execute.drop_task (task_name => v_task_name);
    else
      raise_application_error (-20001, 'ORA in task ' || v_task_name);
  end if;

end;

答案 1 :(得分:0)

除了DBMS_SCHEDULER或较早的DBMS_JOB之外,PL / SQL中没有内置的fork / background提交。 (DBMS_SCHEDULER功能更全面,并且可以更好地跟踪故障。)几年前我作为一个项目编写了一个作业控制对象,但说实话我从未使用它。 www.williamrobertson.net/documents/job-control-object.html

答案 2 :(得分:-2)

您可以使用run_job或提交。

请参阅以下链接,例如: - http://www.dba-oracle.com/r_execute_pl_sql_in_parallel.htm