一尘不染

在SQL Developer中执行异步存储过程

sql

我想使用Oracle SQL Developer异步执行存储过程很多次。

伪代码

var pStatus number
var pOraErrCd varchar2
var pOraErrMsg varchar2
for i 1 .. 1000 -- do async
loop 
    exec myproc('test',:pStatus ,:pOraErrCd ,:pOraErrMsg);
end loop;

存储过程的目的是进行一些插入。为了进行测试,我只想异步执行存储过程很多次。我不在乎任何返回值。

有没有一种 “简便”的 方法来做到这一点?


阅读 140

收藏
2021-03-08

共1个答案

一尘不染

由于您要模拟N个会话,每个会话均调用该过程1000 / N次,因此我可能会执行类似的操作

CREATE OR REPLACE PROCEDURE call_myproc_n_times( p_n IN NUMBER )
AS
  p_status         NUMBER;
  p_ora_error_code VARCHAR2(1000);
  p_ora_error_msg  VARCHAR2(1000);
BEGIN
  FOR i IN 1 .. p_n 
  LOOP
    myproc( 'test', 
            p_status, 
            p_ora_error_code, 
            p_ora_error_msg );
  END LOOP;
END;

DECLARE
  l_num_sessions     number := 10;
  l_exec_per_session number := 100;
  l_jobno            pls_integer;
BEGIN
  FOR i IN 1 .. l_num_sessions
  LOOP
    dbms_job.submit( 
      l_jobno,
      'BEGIN ' ||
      '  call_myproc_n_times( ' || l_exec_per_session || ' ); ' ||
      'END;',
      sysdate + interval '1' minute );
  END LOOP;
  commit;
END;

本示例将启动10个会话,每个会话将快速连续执行该过程100次,前提是您的数据库JOB_QUEUE_PROCESSES至少为10,这意味着允许Oracle在后台同时运行10个作业。创建CALL_MYPROC_N_TIMES过程并不是严格必要的,它只是使构建字符串更容易在工作中执行。

一种替代方法是提交1000个作业,每个作业仅被调用MYPROC一次,并依靠该JOB_QUEUE_PROCESSES参数来限制将同时运行的作业数量。那会行得通,如果您想运行更少的并发会话,那么更改数据库参数就更加困难-L_NUM_SESSIONS在我发布的代码中进行调整很容易。

2021-03-08