Det korta svaret är att du inte kan. Du måste definiera en variabel för varje kolumn som ska returneras.
DECLARE
P_RS SYS_REFCURSOR;
L_T_COL1 T.COL1%TYPE;
L_T_COL1 T.COL2%TYPE;
...
Och hämta sedan till listan med kolumner:
FETCH P_RS INTO L_T_COL1, L_T_COL2, ... ;
Detta är smärtsamt men hanterbart så länge du vet vad du förväntar dig i ref-markören. Använder T.*
i din procedur gör detta dock bräckligt, eftersom att lägga till en kolumn i tabellen skulle bryta koden som tror att den vet vilka kolumner som finns och vilken ordning de är i. (Du kan också bryta den mellan miljöer om tabellerna inte är byggda konsekvent - jag har sett platser där kolumnordningen är olika i olika miljöer). Du vill förmodligen se till att du bara väljer de kolumner som du verkligen bryr dig om, för att undvika att behöva definiera variabler för saker du aldrig kommer att läsa.
Från 11g kan du använda DBMS_SQL
paket för att konvertera din sys_refcursor
till en DBMS_SQL
markören, och du kan fråga den för att bestämma kolumnerna. Bara som ett exempel på vad du kan göra, kommer detta att skriva ut värdet för varje kolumn i varje rad, med kolumnnamnet:
DECLARE
P_RS SYS_REFCURSOR;
L_COLS NUMBER;
L_DESC DBMS_SQL.DESC_TAB;
L_CURS INTEGER;
L_VARCHAR VARCHAR2(4000);
BEGIN
CAPITALEXTRACT(P_RS => P_RS);
L_CURS := DBMS_SQL.TO_CURSOR_NUMBER(P_RS);
DBMS_SQL.DESCRIBE_COLUMNS(C => L_CURS, COL_CNT => L_COLS,
DESC_T => L_DESC);
FOR i IN 1..L_COLS LOOP
DBMS_SQL.DEFINE_COLUMN(L_CURS, i, L_VARCHAR, 4000);
END LOOP;
WHILE DBMS_SQL.FETCH_ROWS(L_CURS) > 0 LOOP
FOR i IN 1..L_COLS LOOP
DBMS_SQL.COLUMN_VALUE(L_CURS, i, L_VARCHAR);
DBMS_OUTPUT.PUT_LINE('Row ' || DBMS_SQL.LAST_ROW_COUNT
|| ': ' || l_desc(i).col_name
|| ' = ' || L_VARCHAR);
END LOOP;
END LOOP;
DBMS_SQL.CLOSE_CURSOR(L_CURS);
END;
/
Det är inte till mycket praktisk användning, och för korthetens skull behandlar jag varje värde som en sträng eftersom jag bara vill skriva ut det ändå. Titta på dokumenten och sök efter exempel för mer praktiska tillämpningar.
Om du bara vill ha ett fåtal kolumner från din referensmarkör kan du, antar jag, gå runt l_desc
och registrera positionen där column_name
är vad du än är intresserad av, som en numerisk variabel; du kan sedan referera till kolumnen med den variabeln senare där du normalt skulle använda namnet i en markörslinga. Beror på vad du gör med datan.
Men om du inte förväntar dig att inte veta vilken kolumnordning du får tillbaka, vilket är osannolikt eftersom du verkar kontrollera proceduren - och förutsatt att du blir av med