Dimungkinkan untuk menanyakan tipe tabel dalam PL/SQL, tetapi hanya tabel dan varray bersarang yang tipenya dideklarasikan pada tingkat skema, yaitu di luar PL/SQL.
Kesalahan
ORA-22905:tidak dapat mengakses baris dari item tabel yang tidak bersarang
berarti Anda mencoba membuat kueri dari jenis tabel yang tidak didukung. Jenis Anda type_tab_AB
adalah array asosiatif, karena INDEX BY BINARY_INTEGER
ayat. Hapus INDEX BY BINARY_INTEGER
klausa untuk membuat type_tab_AB
. Anda jenis tabel bersarang. (Varrays juga akan berfungsi di sini, tetapi saya tidak akan merekomendasikan menggunakannya kecuali Anda mengetahui batas atas untuk jumlah baris yang diharapkan. Saat mendeklarasikan tipe varray, Anda perlu menentukan jumlah maksimum elemen, sedangkan tipe tabel bersarang memiliki tidak ada batasan seperti itu.)
Setelah melakukan perubahan ini, kode Anda mungkin masih tidak berfungsi. Kesalahan berikutnya yang mungkin Anda dapatkan (lihat catatan di bawah jika tidak) adalah
PLS-00642:jenis koleksi lokal tidak diperbolehkan dalam pernyataan SQL
Ini karena tipe yang Anda pilih dideklarasikan di dalam PL/SQL. Anda perlu mendeklarasikan type_tab_AB
, dan record_AB
di luar PL/SQL, menggunakan CREATE TYPE ...
.
Masalah berikutnya yang Anda temui adalah karena kata kunci RECORD
. Jenis rekaman hanya dapat dibuat di dalam PL/SQL, mereka tidak dapat dibuat di tingkat skema. Ubah RECORD
ke OBJECT
untuk memperbaikinya.
Masalah terakhir yang akan Anda temui adalah dengan SELECT t.AA, t.BB BULK COLLECT INTO tab_AB FROM ...
penyataan. Seperti yang terjadi, kueri ini akan memberi Anda kesalahan berikut:
PL/SQL:ORA-00947:nilai tidak cukup
Anda memilih dua item dari setiap baris dan hanya menyediakan satu tabel untuk memasukkan data secara massal. Oracle tidak dapat mengetahui bahwa Anda ingin memasukkan kedua item ke dalam record_AB
Tipe. Anda dapat memperbaikinya dengan cukup mudah dengan mengubah kueri ke SELECT record_AB(t.AA, t.BB) BULK COLLECT INTO tab_AB FROM ...
.
Secara kolektif perubahan ini harus memperbaiki masalah. Berikut adalah skrip SQL*Plus lengkap yang membuat tabel pengujian dengan beberapa data pengujian dan memverifikasi bahwa ia dapat mengkueri jenis tabel:
CREATE TABLE some_table (AA VARCHAR2(16 BYTE), BB VARCHAR2(16 BYTE));
INSERT INTO some_table (AA, BB) VALUES ('aa 1', 'bb 1');
INSERT INTO some_table (AA, BB) VALUES ('aaaaaaaaaa 2', 'b 2');
INSERT INTO some_table (AA, BB) VALUES ('aaaaa 3', 'bbbbbbbbbbbbbb 3');
COMMIT;
VARIABLE curs REFCURSOR;
CREATE OR REPLACE TYPE record_AB AS OBJECT
(
AA VARCHAR2 (16 BYTE),
BB VARCHAR2 (16 BYTE)
);
/
CREATE OR REPLACE TYPE type_tab_AB IS TABLE OF record_AB;
/
DECLARE
tab_AB type_tab_AB;
BEGIN
SELECT record_AB(t.AA, t.BB)
BULK COLLECT INTO tab_AB
FROM some_table t;
OPEN :curs FOR SELECT * FROM TABLE (tab_AB) ;
END;
/
PRINT :curs
Saya telah menempatkan hasil SELECT
ing isi tab_AB
ke kursor, dan menggunakan variabel kursor SQL*Plus untuk membuat daftar isinya. Output yang saya dapatkan ketika menjalankan script pada Oracle 11g XE, setelah semua pesan 'Type Created' dan 'PL/SQL procedure Successfully complete', adalah sebagai berikut:
AA BB
---------------- ----------------
aa 1 bb 1
aaaaaaaaaa 2 b 2
aaaaa 3 bbbbbbbbbbbbbb 3
CATATAN: Untuk kesederhanaan, saya berasumsi penanya menggunakan Oracle 11 atau lebih lama. Di Oracle 12, saya yakin Anda diizinkan untuk menggunakan tipe yang dideklarasikan dalam PL/SQL dalam kueri SQL, jadi Anda mungkin tidak menemukan kesalahan PLS-00642. Saya tidak bisa mengatakan perubahan lain apa pada jawaban saya yang mungkin juga diperlukan untuk Oracle 12 karena saya belum menggunakan Oracle 12.