views:

50

answers:

1

I had a 'procedure A' in which it has to return a null cursor to front end and then immediately it should continue with the next step in which it will call a procedure which will take 20 min to complete the proc.

Procedure A(cur_out refcursor)
begin

 OPEN cur_out  for
 select 
 null empname,
 null empid
 from dual;

procedure B();//Will take 20 min

end;

Here the 'Procedure A' should return the null cursor without waiting for the 'Procedure B' to complete.

How to implement this in oracle.

Thanks in advance.

+5  A: 

Assuming that you don't need procedure B to run in the same session as A, you can schedule the job to run asynchronously, i.e.

CREATE OR REPLACE PROCEDURE a( p_cur_out OUT SYS_REFCURSOR )
AS
  l_jobno pls_integer;
BEGIN
  OPEN p_cur_out 
   FOR SELECT cast( null as varchar2(64) ) empname, 
              cast( null as integer ) empid
         FROM dual;

  dbms_job.submit( l_jobno,
                   'BEGIN B(); END;' );
  commit;
END a;

You'll return from A and a job will be scheduled immediately to run procedure B in a separate session (note that the job won't start until the current session commits which is why I added a commit here-- if your code is going to commit elsewhere, you can eliminate that). All dbms_job.submit is doing is creating the job-- the job will not start executing until after the procedure returns.

If B takes arguments, you'll need to build the PL/SQL block dynamically. So if B takes two NUMBER parameters

CREATE OR REPLACE PROCEDURE a( p_cur_out OUT SYS_REFCURSOR )
AS
  l_jobno  pls_integer;
  l_param1 pls_integer;
  l_param2 pls_integer;
BEGIN
  OPEN p_cur_out 
   FOR SELECT cast( null as varchar2(64) ) empname, 
              cast( null as integer ) empid
         FROM dual;

  dbms_job.submit( l_jobno,
                   'BEGIN B(' || to_char( l_param1 ) || ', ' ||
                                 to_char( l_param2 ) || '); END;' );
  commit;
END a;
Justin Cave
I cannot think of any other way. Running the two "threads" in the same transaction seems completely impossible.
Thilo
This is fine ...But a small doubt ..Do the 'Proecure a' will wait for the dbms_job.submit l_jobno,'BEGIN B(); END;' ); to complete or simply it will be triggered and the procedure a will be ended.
K Ratnajyothi
It waits for the DBMS_JOB.SUBMIT to complete, yes. But that happens nearly instantaneously. Procedure B will be executed some time later in a separate session.
Justin Cave
One more doubt if the procedure B is having some arguments like B(arg1,arg2)...How to schedule the that procedure B with dbms_job.submit.......dbms_job.submit(l_jobno,'BEGIN B(arg1,arg2); END;);.........Since it throwing errors while passing these arguments in this way...do we need to follow some format while passing the arguments to the procedure B which is a dbms_job.
K Ratnajyothi
Added additional information to show how to pass parameters
Justin Cave
CREATE OR REPLACE PROCEDURE a(l_param1 varchar2(20), l_param2 varchar2(20), p_cur_out OUT SYS_REFCURSOR ) AS l_jobno pls_integer; BEGIN OPEN p_cur_out FOR SELECT cast( null as varchar2(64) ) empname, cast( null as integer ) empid FROM dual; dbms_job.submit( l_jobno, 'BEGIN B(' || l_param1 || ', ' || l_param2 || '); END;' ); commit; END a;
K Ratnajyothi
K Ratnajyothi
@K Ratnajyothi- Parameters to a stored procedure are declared as VARCHAR2, not VARCHAR2(20).
Justin Cave
Corrected the declaration as varchar2 but not varchar2(20).......... Still it showing the same problem as mentioned. and aslo we are running the dbmsjob which was submitted as dbms_job.run(l_jobno);..............But not executed properly
K Ratnajyothi
Can you post the signature of B? Are you expecting that the second parameter to A is really going to be a DATE?
Justin Cave