Krótka odpowiedź brzmi: nie możesz. Będziesz musiał 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 potem sprowadzić do listy kolumn:
FETCH P_RS INTO L_T_COL1, L_T_COL2, ... ;
Jest to bolesne, ale do opanowania tak długo, jak wiesz co czekasz w ref kursora. Używanie w procedurze T.*
powoduje, że jest to delikatne, ponieważ dodanie kolumny do tabeli spowodowałoby złamanie kodu, który wydaje się, że wie, jakie kolumny istnieją i w jakiej kolejności się znajdują. (Możesz również podzielić go między środowiska, jeśli tabele nie są ustawione) t budowane konsekwentnie - widziałem miejsca, w których kolejność kolumn jest różna w różnych środowiskach). Prawdopodobnie będziesz chciał upewnić się, że wybierasz tylko te kolumny, na których tak naprawdę zależy, aby uniknąć konieczności definiowania zmiennych dla rzeczy, których nigdy nie przeczytasz.
Od 11g można użyć pakietu DBMS_SQL
, aby przekonwertować swój sys_refcursor
na kursor DBMS_SQL
i można go przesłuchać w celu ustalenia kolumn. Tylko jako przykład tego, co można zrobić, to wydrukować wartość każdej kolumnie w każdym wierszu 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;
/
to nie jest znacznie praktyczne zastosowanie, a dla zwięzłości ja traktując każdy wartość jako ciąg znaków, ponieważ po prostu chcę go wydrukować. Przejrzyj dokumenty i wyszukaj przykłady dla bardziej praktycznych zastosowań.
Jeśli potrzebujesz tylko kilku kolumn z kursora ref, możesz, jak przypuszczam, wykonać pętlę około l_desc
i zapisać pozycję, w której column_name
jest tym, co cię interesuje, jako zmienną numeryczną; możesz później odnieść się do kolumny przez tę zmienną, w której normalnie używałbyś tej nazwy w pętli kursora. Zależy od tego, co robisz z danymi.
Ale jeśli nie jesteś spodziewa nie wiedzieć kolejność kolumn dostajesz z powrotem, co jest mało prawdopodobne, ponieważ wydają się kontrolować procedurę - i zakładając, że pozbyć się .*
s - jesteś prawdopodobnie znacznie lepiej zmniejszyć zwracane kolumny do minimum i po prostu zadeklarować je wszystkie indywidualnie.
Awesome man, szukałem roku, jak to zrobić i to wyjaśniło to najlepiej. Uwaga: Nie potrzebowałem CAPITALEXTRACT (P_RS => P_RS); linia. (w rzeczywistości to się zepsuło, nie byłem pewien, co zrobił, więc skomentowałem i mój pl/sql następnie działał wspaniale) – armyofda12mnkeys
@ armyofda12mnkeys - cieszę się, że pomogło. CAPITALEXTRACT był funkcją specyficzną dla tego pytania, a nie czymś nieodłącznym dla rozwiązania, więc nie martw się o to. –