Como declarar parâmetro ref cursor a um método de objeto?
-
13-09-2019 - |
Pergunta
Eu sou um pouco novo para PL / SQL e precisa de algo que parece um pouco com isto:
create type base as object (
unused number,
member procedure p( c in ref cursor )
) not final;
create type child1 under base (
overriding member procedure p( c in ref cursor ) as
t table1%rowtype
begin
fetch c into t;
-- process table1 row
end;
);
create type child2 under base (
overriding member procedure p( c in ref cursor ) as
t table2%rowtype
begin
fetch c into t;
-- process table2 row
end;
);
procedure generic_handler( o in base, c in ref cursor ) as
begin
o.p( c );
end;
o1 child1 := child1(0)
o2 child2 := child2(0)
c ref cursor
open c for select * from table1;
generic_handler( o1, c );
open c for select * from table2;
generic_handler( o2, c );
Basicamente, eu preciso de uma única rotina genérica que sabe como executar uma ação independente de mesa delegar tarefas específicas da tabela para uma classe derivada.
Os métodos de objetos acima tomando 'ref do cursor não compilar - compilador diz' necessidades do cursor para ser definidos. Então é claro que eu tentei 'tipo generic_cursor como cursor ref' em todo o lugar, mas não pode obtê-lo para compilar.
Eu achei muito bonito nada ao tentar rastrear a sintaxe para passar cursores REF para métodos de objetos. E isso me fez pensar que talvez eu estou tentando fazer algo estúpido.
Será que o que estou tentando fazer faz sentido? Se assim for, o que eu estou ausente? Onde posso definir o generic_cursor para que eu possa usá-lo como um tipo de parâmetro método de objeto?
Solução
O seu código irá funcionar uma vez que você resolver os erros sintáticos.
SQL> create or replace type base as object
2 ( unused number
3 , member procedure p( c in sys_refcursor )
4 )
5 not final;
6 /
Type created.
SQL>
SQL> create or replace type child1 under base (
2 overriding member procedure p( c in sys_refcursor )
3 );
4 /
Type created.
SQL> create or replace type body child1 as
2 overriding member procedure p( c in sys_refcursor )
3 as
4 t dept%rowtype;
5 begin
6 loop
7 fetch c into t;
8 exit when c%notfound;
9 dbms_output.put_line('dname='||t.dname);
10 end loop;
11 end;
12 end;
13 /
Type body created.
SQL>
SQL> create or replace type child2 under base (
2 overriding member procedure p( c in sys_refcursor )
3 );
4 /
Type created.
SQL> create or replace type body child2 as
2 overriding member procedure p( c in sys_refcursor )
3 as
4 t emp%rowtype;
5 begin
6 loop
7 fetch c into t;
8 exit when c%notfound;
9 dbms_output.put_line('ename='||t.ename);
10 end loop;
11 end;
12 end;
13 /
Type body created.
SQL>
SQL>
SQL> create or replace procedure generic_handler
2 ( o in out base, c in sys_refcursor )
3 as
4 begin
5 o.p( c );
6 end;
7 /
Procedure created.
SQL>
SQL> set serveroutput on size unlimited
SQL>
SQL> declare
2 o1 child1 := child1(0);
3 o2 child2 := child2(0);
4 rc sys_refcursor;
5 begin
6 open rc for select * from dept where deptno = 10;
7 o1.p(rc);
8 open rc for select * from emp where deptno = 10;
9 o2.p(rc);
10 end;
11 /
dname=ACCOUNTING
ename=BOEHMER
ename=SCHNEIDER
ename=KISHORE
PL/SQL procedure successfully completed.
SQL>
A documentação do Oracle é muito difícil de entender quando você é novo. Eu acho que no seu caso, você precisa saber que o Object_Oriented coisas está em um livro diferente do regular, PL / SQL informações . Você provavelmente terá que verificar tanto quando você está perplexo.