Oracle
 sql >> Database >  >> RDS >> Oracle

Restituisce più valori dalla funzione Oracle

Aggiornamento:

Sì, possiamo usare un riferimento al cursore (SYS_REFCURSOR) e OPEN/FETCH/CLOSE invece di un CURSOR e CURSOR FOR LOOP.

La sintassi è OPEN <cursor-reference> FOR <string-containing-sql-statement> . Vedi sotto.

CREATE OR REPLACE FUNCTION load_test_object_sn
RETURN test_otable_sn
AS  
  details test_otable_sn := test_otable_sn();

  -- Variable stores SQL statement for cursor
  l_sql CLOB :=
    q'[with ad as (
         select 'a' column_1, 'b' column_2, 4 column_3 from dual union all
         select 'r', '5', 3  from dual union all 
         select 'g', 's', 3  from dual
       )
       select *
         from ad]';

  -- Cursor reference allows us to open cursor for SQL statement above
  rc SYS_REFCURSOR;

  -- Define object instance to store each row fetched from the cursor
  l_obj test_object_sn := test_object_sn(NULL, NULL, NULL);

  i PLS_INTEGER := 1;
BEGIN

  -- Explicitly open, fetch from, and close the cursor
  OPEN rc FOR l_sql;
  LOOP
    FETCH rc INTO l_obj.column_1, l_obj.column_2, l_obj.column_3;
    EXIT WHEN rc%NOTFOUND;
    details.extend();
    details(i) := test_object_sn(l_obj.column_1, l_obj.column_2, l_obj.column_3);
    i := i + 1;
  END LOOP;
  CLOSE rc;

  RETURN details;
END;

Risposta originale:

Sfortunatamente, non è possibile utilizzare SELECT * INTO con una raccolta in questo modo, quindi ecco un modo alternativo per popolare la tabella:

create or replace function load_test_object_sn
return test_otable_sn
as  
    details test_otable_sn := test_otable_sn();
    cursor c_ad is
    with ad as (select 'a' column_1, 'b' column_2, 4 column_3   from dual
    union all 
    select 'r', '5', 3  from dual
    union all
    select 'g', 's', 3  from dual)
    select * from ad;
    i pls_integer := 1;

begin

   for ad_rec in c_ad loop     
      details.extend();
      details(i) := test_object_sn(ad_rec.column_1, ad_rec.column_2, ad_rec.column_3);
      i := i + 1;
   end loop;

    return details;
end;
/

Uscita:

SQL> SELECT * FROM TABLE(load_test_object_sn);

COLUMN_1   COLUMN_2     COLUMN_3
---------- ---------- ----------
a          b                   4
r          5                   3
g          s                   3