如何在pl / sql

时间:2016-05-12 06:01:58

标签: oracle session stored-procedures plsql

PL / SQL中是否有可能同时调用多个会话并在多个会话中运行一个过程。

我希望在有250个用户登录应用程序的实时应用程序中使用它。用户通过客户端工具连接到Oracle。 (Power Builder是前端工具)

例如,如果用户调用存储过程,则该存储过程必须使用不同的参数值运行10次。
我不想在同一个会话中一个接一个地连续运行10次,因为这可能需要很长时间。
我正在寻找一种方法,我可以同时在10个不同的会话中运行存储过程。

我考虑过使用DBMS_JOB.SUBMIT放置10个作业,但是因为 繁重的工作量(250个用户* 10 = 2500个工作可能同时在Job Scheduler中安排等等)我们的DBA小组正在寻找其他更好的方法。

2 个答案:

答案 0 :(得分:2)

为避免发布多个Oracle职位,您可以尝试使用William Robertson Parallel PL/SQL launcher

  

如果你创建一个表" PQ_DRIVER"有4个分区,并行度为4,每个分区有一行,你按照" SELECT /*+ PARALLEL(pq,4) */ thread_id FROM pq_driver pq"的行执行查询,这应该说服PQ控制器设置4个PQ奴隶进程在它上面工作(每个分区一个)。如果您将该查询作为游标参数传递给并行启用的流水线函数,那么不应该创建一个情况,其中每一行都由一个单独的PQ从属进程处理?所以这是一种使用(好的,黑客)PQ引擎的方法,以便它并行处理任意PL / SQL过程调用。

我们的想法是使用 PARALLEL_ENABLE PIPELINED 功能创建一个功能:

   function pq_submit
    ( p_job_list  varchar2_tt
    , p_pq_refcur rc_pq_driver )
    return varchar2_tt
    parallel_enable(partition p_pq_refcur by any)
    pipelined
 is
 ...
 loop
   execute_command(your_proc);
 end loop;

功能execute_command使用 autonomous_transaction

看起来像这样:

procedure execute_command
  ( p_what log_times.what%type )
is
  pragma autonomous_transaction;
begin
  execute immediate p_what;
  commit;
end execute_command;

答案 1 :(得分:2)

除了创建JOB之外,您还可以使用DBMS_PARALLEL_EXECUTE package

这里有一些点击:

create_chunks_by_sqlby_rowid => FALSE一起使用,即使用ID并创建与所需存储过程执行完全相同的块数。

run_task中将parallel_level设置为所需的并行度。如果你需要节流并行性,这个数字与上面相同或更低。

通过电话 过程作为参数sql_stmt,例如

BEGIN
  test_proc(:start_id,:end_id);
END;

如您所见,可以选择将块号传递给过程,因此您可以将其用作threadId

这是一个完整的例子

创建任务和3个块

DECLARE
  l_stmt CLOB;
BEGIN
  DBMS_PARALLEL_EXECUTE.create_task (task_name => 'parallel PL/SQL');

  l_stmt := 'SELECT rownum, rownum FROM dual connect by level <= 3';

  DBMS_PARALLEL_EXECUTE.create_chunks_by_sql(task_name => 'parallel PL/SQL',
                                             sql_stmt  => l_stmt,
                                             by_rowid  => FALSE);
END;
/

使用DOP = 3

运行任务
DECLARE
  l_sql_stmt VARCHAR2(32767);
BEGIN
  l_sql_stmt := 'BEGIN
                   test_proc(:start_id,:end_id);
                END;';   

  DBMS_PARALLEL_EXECUTE.run_task(task_name      => 'parallel PL/SQL',
                                 sql_stmt       => l_sql_stmt,
                                 language_flag  => DBMS_SQL.NATIVE,
                                 parallel_level => 3);
END;
/

删除任务

BEGIN
  DBMS_PARALLEL_EXECUTE.drop_task('parallel PL/SQL');
END;
/