Krátká odpověď je, nemůžete. Pro každý sloupec, který bude vrácen, budete muset definovat proměnnou.
DECLARE
P_RS SYS_REFCURSOR;
L_T_COL1 T.COL1%TYPE;
L_T_COL1 T.COL2%TYPE;
...
A pak načtěte do seznamu sloupců:
FETCH P_RS INTO L_T_COL1, L_T_COL2, ... ;
To je bolestivé, ale zvládnutelné, pokud víte, co v referenčním kurzoru očekáváte. Pomocí T.*
ve vašem postupu je to však křehké, protože přidání sloupce do tabulky by narušilo kód, který si myslí, že ví, jaké sloupce tam jsou a v jakém jsou pořadí. (Můžete to také rozdělit mezi prostředími, pokud tabulky nejsou vytvořeny konzistentně - viděl jsem místa, kde se řazení sloupců v různých prostředích liší). Pravděpodobně se budete chtít ujistit, že vybíráte pouze sloupce, které vás opravdu zajímají, abyste nemuseli definovat proměnné pro věci, které nikdy nečtete.
Od 11g můžete používat DBMS_SQL
balíček pro převod vašeho sys_refcursor
do DBMS_SQL
kurzor a můžete to zjistit, abyste určili sloupce. Jako příklad toho, co můžete udělat, se vytiskne hodnota každého sloupce v každém řádku s názvem sloupce:
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;
/
To není příliš praktické použití a pro stručnost zacházím s každou hodnotou jako s řetězcem, protože ji chci stejně vytisknout. Podívejte se na dokumenty a vyhledejte příklady pro praktičtější aplikace.
Pokud chcete z referenčního kurzoru jen několik sloupců, mohli byste, předpokládám, zacyklit kolem l_desc
a zaznamenejte pozici, kde je column_name
je cokoli, co vás zajímá, jako číselná proměnná; pak byste mohli později odkazovat na sloupec touto proměnnou, kde byste normálně použili název v kurzorové smyčce. Záleží, co s daty děláte.
Ale pokud neočekáváte neznáte pořadí sloupců, které dostáváte zpět, což je nepravděpodobné, protože se zdá, že postup ovládáte - a za předpokladu, že se zbavíte .*
s – pravděpodobně mnohem lépe zredukujete vrácené sloupce na minimum, které potřebujete, a deklarujete je všechny jednotlivě.