Oracle
 sql >> Teknologi Basis Data >  >> RDS >> Oracle

ORA-22905 - saat menanyakan jenis tabel dengan pernyataan pilih

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.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Cara mengkloning pengguna di Oracle

  2. Nilai Daftar Sisipan MyBatis

  3. Cara menggunakan fungsi Analitik di oracle (Over Partition by Keyword)

  4. Bagaimana cara mematikan kedaluwarsa kata sandi Oracle?

  5. Referensi tabel dalam skema lain yang menghilangkan nama skema