2013-02-07 1 views
0

Dans mon esprit, j'écris une fonction telle que l'appel quelque chose commeWrap sélectionner une fonction Oracle

select get_foo() from dual; 

ou

select * from table (get_foo); 

renvoie le même résultat que

select * from foo; 

Donc, j'ai une fonction qui compile ...

create or replace function get_foo return sys_refcursor as 
    rc_foo sys_refcursor; 
begin 
    open rc_foo for 'select * from foo'; 
    return rc_foo; 
end; 

mais sélectionnez get_foo() à partir du double renvoie 1 ligne.

((ID=1,NAME=Sarah1),(ID=2,NAME=Sarah2),(ID=3,NAME=Sarah3),) 

tandis que select * de la table (get_foo()) me donne ORA-22905. Comment puis-je modifier la définition de la fonction et/ou l'appel pour obtenir le résultat souhaité?

Répondre

1

vous utilisez une fonction pipelined.

par exemple:

SQL> create table foo(id , name) as select rownum, 'Sarah'||rownum from dual connect by level <= 3; 

Table created. 

SQL> create or replace package pipeline_test 
    2 as 
    3 type foo_tab is table of foo%rowtype; 
    4 function get_foo 
    5  return foo_tab PIPELINED; 
    6 end; 
    7/

Package created. 

SQL> create or replace package body pipeline_test 
    2 as 
    3 function get_foo 
    4  return foo_tab PIPELINED 
    5 is 
    6  v_rc sys_refcursor; 
    7    t_foo foo_tab; 
    8 
    9 begin 
10  open v_rc for select * from foo; 
11  loop 
12  fetch v_rc bulk collect into t_foo limit 100; 
13  exit when t_foo.count = 0; 
14  for idx in 1..t_foo.count 
15  loop 
16   pipe row(t_foo(idx)); 
17  end loop; 
18  end loop; 
19 end; 
20 end; 
21/

Package body created. 

SQL> select * from table(pipeline_test.get_foo()); 

     ID NAME 
---------- --------------------------------------------- 
     1 Sarah1 
     2 Sarah2 
     3 Sarah3 
+0

Merci. Ceci est raisonnablement clair. J'essaie toujours de me faire une idée des pipelining et des paquets. Sont-ils nécessaires pour obtenir l'effet désiré? De plus, y a-t-il un impact (significatif) sur la sélection dans un curseur puis sur une boucle –

+0

@SarahPhillips en fonction de la taille de l'ensemble de résultats, vous pouvez améliorer cela en utilisant bulk collect (avec une limite de 100) réduire les récupérations par ligne renvoyée. c'est-à-dire quelque chose comme 'fetch v_rc bulk collect dans t_foo;' où 't_foo' est une table de' r_foo', bouclant ensuite ce tableau de sortie et canalisant la sortie. – DazzaL

+0

@SarahPhillips p.ex. voir modifier pour cela – DazzaL

Questions connexes