【问题标题】:Parallel execute oracle PL/SQL [duplicate]并行执行 oracle PL/SQL [重复]
【发布时间】:2016-09-15 15:00:39
【问题描述】:

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

现在...我正在尝试改进代码以最大程度地减少执行时间,然后我意识到每个验证和插入信息的 SP into table 不依赖于其他 SP 信息,所以我问是否有办法并行调用所有这些 SP。

今天

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

【问题讨论】:

    标签: oracle plsql parallel-processing package


    【解决方案1】:

    作为使用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;
    

    【讨论】:

      【解决方案2】:

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

      【讨论】:

        【解决方案3】:

        您可以使用 run_job 或提交。

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-02-14
          • 1970-01-01
          • 2013-08-16
          • 1970-01-01
          • 2018-07-01
          • 2017-10-18
          相关资源
          最近更新 更多