Jawaban singkatnya adalah, Anda tidak bisa. Anda perlu mendefinisikan variabel untuk setiap kolom yang akan dikembalikan.
DECLARE
P_RS SYS_REFCURSOR;
L_T_COL1 T.COL1%TYPE;
L_T_COL1 T.COL2%TYPE;
...
Dan kemudian ambil ke dalam daftar kolom:
FETCH P_RS INTO L_T_COL1, L_T_COL2, ... ;
Ini menyakitkan tetapi dapat dikelola selama Anda tahu apa yang Anda harapkan di kursor ref. Menggunakan T.*
dalam prosedur Anda membuat ini rapuh, karena menambahkan kolom ke tabel akan merusak kode yang menganggapnya tahu kolom apa yang ada dan urutannya. (Anda juga dapat memecahnya di antara lingkungan jika tabel tidak dibuat secara konsisten - Saya telah melihat tempat-tempat di mana pemesanan kolom berbeda di lingkungan yang berbeda). Anda mungkin ingin memastikan bahwa Anda hanya memilih kolom yang benar-benar Anda pedulikan, untuk menghindari keharusan mendefinisikan variabel untuk hal-hal yang tidak akan pernah Anda baca.
Dari 11g Anda dapat menggunakan DBMS_SQL
paket untuk mengonversi sys_refcursor
. Anda menjadi DBMS_SQL
kursor, dan Anda dapat menginterogasinya untuk menentukan kolom. Sebagai contoh dari apa yang dapat Anda lakukan, ini akan mencetak nilai setiap kolom di setiap baris, dengan nama kolom:
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;
/
Itu tidak banyak berguna secara praktis, dan untuk singkatnya saya memperlakukan setiap nilai sebagai string karena saya hanya ingin mencetaknya. Lihat dokumen dan cari contoh untuk aplikasi yang lebih praktis.
Jika Anda hanya menginginkan beberapa kolom dari kursor ref Anda, saya kira, Anda dapat memutar l_desc
dan catat posisi dimana column_name
adalah apa pun yang Anda minati, sebagai variabel numerik; Anda kemudian bisa merujuk ke kolom dengan variabel itu nanti di mana Anda biasanya menggunakan nama itu dalam loop kursor. Tergantung apa yang Anda lakukan dengan data tersebut.
Tapi kecuali jika Anda mengharapkan untuk tidak mengetahui urutan kolom yang Anda dapatkan kembali, yang tidak mungkin karena Anda tampaknya mengontrol prosedur - dan dengan asumsi Anda menyingkirkan .*
s - Anda mungkin jauh lebih baik mengurangi kolom yang dikembalikan seminimal mungkin dan mendeklarasikan semuanya satu per satu.