Oracle
 sql >> Baza danych >  >> RDS >> Oracle

jak zadeklarować % ROWTYPE zmiennej, która jest słabo wpisanym SYS_REFCURSOR?

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.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Oracle usuwa wiersze z wielu tabel

  2. Jak przekazać XML jako parametr do procedury składowanej w Oracle?

  3. Szaleństwo wersji sterownika Oracle jdbc

  4. 27 skryptów Oracle dba dla bazy danych Oracle dla administracji i monitorowania

  5. Informacje o elemencie formatu RM w Oracle