Oracle
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Oracle

ORA-22905 - khi truy vấn loại bảng bằng câu lệnh select

Có thể truy vấn các kiểu bảng trong PL / SQL, nhưng chỉ các bảng và varrays lồng nhau có kiểu được khai báo ở cấp giản đồ, tức là bên ngoài PL / SQL.

Lỗi

ORA-22905:không thể truy cập các hàng từ một mục bảng không lồng nhau

có nghĩa là bạn đang cố gắng truy vấn từ một loại bảng không được hỗ trợ. Loại của bạn type_tab_AB là một mảng kết hợp, vì INDEX BY BINARY_INTEGER mệnh đề. Xóa INDEX BY BINARY_INTEGER mệnh đề tạo type_tab_AB của bạn một loại bảng lồng nhau. (Varrays cũng sẽ hoạt động ở đây, nhưng tôi không khuyên bạn nên sử dụng chúng trừ khi bạn biết giới hạn trên cho số hàng mong đợi. Khi khai báo kiểu varray, bạn cần chỉ định số phần tử tối đa, trong khi các kiểu bảng lồng nhau có không hạn chế như vậy.)

Sau khi thực hiện thay đổi này, mã của bạn có thể vẫn không hoạt động. Lỗi tiếp theo mà bạn có thể gặp phải (xem ghi chú ở dưới cùng nếu không) là

PLS-00642:kiểu tập hợp cục bộ không được phép trong câu lệnh SQL

Điều này là do kiểu bạn đang chọn được khai báo bên trong PL / SQL. Bạn cần khai báo type_tab_ABrecord_AB bên ngoài PL / SQL, sử dụng CREATE TYPE ... .

Vấn đề tiếp theo bạn gặp phải là do từ khóa RECORD . Các loại bản ghi chỉ có thể được tạo bên trong PL / SQL, chúng không thể được tạo ở cấp lược đồ. Thay đổi RECORD thành OBJECT để khắc phục điều này.

Vấn đề cuối cùng bạn sẽ gặp phải là với SELECT t.AA, t.BB BULK COLLECT INTO tab_AB FROM ... tuyên bố. Như hiện tại, truy vấn này sẽ cung cấp cho bạn lỗi sau:

PL / SQL:ORA-00947:không đủ giá trị

Bạn đang chọn hai mục từ mỗi hàng và chỉ cung cấp một bảng để chèn hàng loạt dữ liệu vào. Oracle hoàn toàn không thể tìm ra rằng bạn muốn nhét hai mục vào record_AB của mình gõ phím. Bạn có thể khắc phục điều này khá dễ dàng bằng cách thay đổi truy vấn thành SELECT record_AB(t.AA, t.BB) BULK COLLECT INTO tab_AB FROM ... .

Nói chung, những thay đổi này sẽ khắc phục sự cố. Đây là tập lệnh SQL * Plus đầy đủ tạo bảng kiểm tra với một số dữ liệu kiểm tra và xác minh rằng nó có thể truy vấn loại bảng:

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

Tôi đã đặt kết quả của SELECT nhập nội dung của tab_AB vào một con trỏ và sử dụng biến con trỏ SQL * Plus để liệt kê nội dung của nó. Kết quả mà tôi nhận được khi chạy tập lệnh trên Oracle 11g XE, sau khi tất cả các thông báo 'Kiểu đã tạo' và 'Thủ tục PL / SQL đã hoàn tất thành công', như sau:

AA               BB
---------------- ----------------
aa 1             bb 1
aaaaaaaaaa 2     b 2
aaaaa 3          bbbbbbbbbbbbbb 3

LƯU Ý: Để đơn giản, tôi đã giả định rằng người hỏi đang sử dụng Oracle 11 trở lên. Trong Oracle 12, tôi tin rằng bạn được phép sử dụng các kiểu được khai báo trong PL / SQL trong một truy vấn SQL, vì vậy bạn có thể không gặp phải lỗi PLS-00642. Tôi không thể nói những thay đổi nào khác đối với câu trả lời của tôi cũng có thể cần thiết cho Oracle 12 vì tôi vẫn chưa sử dụng 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. ORACLE - Chọn Đếm trên Truy vấn con

  2. Kiểm tra bảng tồn tại hay không trước khi tạo nó trong Oracle

  3. Cơ sở dữ liệu:Hàm Pipelined

  4. FNDCPASS &AFPASSWD

  5. Khai báo một biến và đặt giá trị của nó từ một truy vấn SELECT trong Oracle