它可以查詢在PL/SQL表類型,但只有嵌套表和可變數組,其類型在架構層面,即PL/SQL外部的聲明。
錯誤
ORA-22905: cannot access rows from a non-nested table item
意味着你正試圖從一個不表類型進行查詢。由於INDEX BY BINARY_INTEGER
子句,您的類型type_tab_AB
是一個關聯數組。刪除INDEX BY BINARY_INTEGER
子句以使您的type_tab_AB
爲嵌套表類型。 (Varrays也可以在這裏工作,但我不建議使用它們,除非你知道預期行數的上限。當聲明一個varray類型時,你需要指定最大元素數,而嵌套表類型有沒有這樣的限制。)
做出這一改變後,你的代碼可能仍然不起作用。下一個錯誤,你可能會得到(見注在底部,如果你不這樣做)是
PLS-00642: local collection types not allowed in SQL statements
這是因爲你選擇到類型PL/SQL中聲明。您需要在PL/SQL之外聲明type_tab_AB
和record_AB
,使用CREATE TYPE ...
。
您遇到的下一個問題將是因爲關鍵字RECORD
。記錄類型只能在PL/SQL中創建,they cannot be created at schema level。將RECORD
更改爲OBJECT
以解決此問題。
您將遇到的最後一個問題是SELECT t.AA, t.BB BULK COLLECT INTO tab_AB FROM ...
聲明。既然這樣,這個查詢會給你以下錯誤:
PL/SQL: ORA-00947: not enough values
您的選擇會從每排兩個項目和正在提供只有一個表中的數據批量插入。 Oracle不能完全弄清楚你想把這兩個項目填入你的record_AB
類型。通過將查詢更改爲SELECT record_AB(t.AA, t.BB) BULK COLLECT INTO tab_AB FROM ...
,可以很容易地解決此問題。
總的來說,這些更改應該可以解決問題。這裏有一個完整的SQL * Plus腳本,與一些測試數據創建一個測試表,並驗證它是否可以查詢表類型:
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
我就把SELECT
荷蘭國際集團的tab_AB
內容,結果變成光標,並使用SQL * Plus遊標變量來列出其內容。輸出當我運行的Oracle 11g XE劇本我得到的,畢竟和「PL/SQL過程已成功完成」的消息,在「創造型」的情況如下:
AA BB
---------------- ----------------
aa 1 bb 1
aaaaaaaaaa 2 b 2
aaaaa 3 bbbbbbbbbbbbbb 3
注:爲了簡化,我假設提問者正在使用Oracle 11或更早的版本。在Oracle 12中,我相信你可以在SQL查詢中使用PL/SQL中聲明的類型,所以你可能不會遇到PLS-00642錯誤。我不能說我的答案還有什麼其他更改對於Oracle 12來說可能也是必需的,因爲我還沒有使用Oracle 12.
我認爲這需要更多的上下文。你能發佈一個演示這個錯誤的_complete_最小的例子嗎?你必須在你的程序中用多個記錄填充'tab_AB',以便在這種情況下工作,在這種情況下你爲什麼要選擇這個變量。 – Ben