Krótka odpowiedź brzmi:nie możesz. Musisz zdefiniować zmienną dla każdej kolumny, która zostanie zwrócona.
DECLARE
P_RS SYS_REFCURSOR;
L_T_COL1 T.COL1%TYPE;
L_T_COL1 T.COL2%TYPE;
...
A następnie pobierz na listę kolumn:
FETCH P_RS INTO L_T_COL1, L_T_COL2, ... ;
Jest to bolesne, ale możliwe do opanowania, o ile wiesz, czego oczekujesz od kursora ref. Korzystanie z T.*
w Twojej procedurze sprawia to jednak, że jest to delikatne, ponieważ dodanie kolumny do tabeli złamałoby kod, który sądzi, że wie jakie są kolumny i w jakiej kolejności. (Możesz również przerwaćto między środowiskami, jeśli tabele nie sązbudowane konsekwentnie - widziałem miejsca, w których kolejność kolumn jest inna w różnych środowiskach). Prawdopodobnie i tak będziesz chciał się upewnić, że wybierasz tylko te kolumny, na których naprawdę Ci zależy, aby uniknąć konieczności definiowania zmiennych dla rzeczy, których nigdy nie przeczytasz.
Od 11g możesz używać DBMS_SQL
pakiet do konwersji sys_refcursor
w DBMS_SQL
kursora i możesz to sprawdzić, aby określić kolumny. Jako przykład tego, co możesz zrobić, zostanie wydrukowana wartość każdej kolumny w każdym wierszu wraz z nazwą kolumny:
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;
/
Nie jest to zbyt praktyczne, a dla zwięzłości traktuję każdą wartość jako ciąg, ponieważ i tak chcę ją wydrukować. Zapoznaj się z dokumentacją i wyszukaj przykłady bardziej praktycznych zastosowań.
Jeśli chcesz tylko kilka kolumn z kursora ref, możesz, jak sądzę, zapętlić l_desc
i zapisz pozycję, w której column_name
jest tym, czym jesteś zainteresowany, jako zmienną liczbową; możesz później odwołać się do kolumny za pomocą tej zmiennej, gdzie normalnie używałbyś nazwy w pętli kursora. Zależy od tego, co robisz z danymi.
Ale chyba spodziewasz się nie znać kolejności kolumn, którą otrzymujesz, co jest mało prawdopodobne, ponieważ wydajesz się kontrolować procedurę - i zakładając, że pozbyłeś się .*
s - prawdopodobnie znacznie lepiej będzie ograniczyć zwracane kolumny do niezbędnego minimum i po prostu zadeklarować je wszystkie indywidualnie.