2015-12-24 103 views
1

我只是試圖實現管道行嵌套類型。周圍有很多例子,但沒有我能夠應用的例子。管道嵌套對象類型

我的類型是:

create type t1_row as object (a1 number, a2 varchar2(10)); 
create type t1_tab as table of t1_row; 
create type t2_row as object (b1 number, b2 varchar2(10), b3 t1_tab); 
create type t2_tab as table of t2_row; 

我試圖創建在許多方面的功能,但沒有人能夠成功編譯。

一個例子:

create or replace function fn (r in number) return t2_row pipelined is 
    l_row1 t1_tab; 
    l_row2 t2_tab; 
begin 
    for i in 1..r loop    
     for j in 1..r loop 
      l_row1(j).a1 := j; 
      l_row1(j).a2 := 'a2 ' || j; 
     end loop; 
     l_row2(i) := (i,l_row1); 
     PIPE ROW (l_row2); 
    end loop; 
    return; 
end; 

此代碼產生以下錯誤:

[錯誤] PLS-00630(1:12):PLS-00630:流水線的功能必須有一個支持的集合返回類型

[錯誤] PLS-00382(10:22):PLS-00382:表達式是錯誤的類型

任何幫助建議或任何類似的例子都可能有用。

版本:Oracle 11g發行11.2.0.1.0

+0

什麼錯誤,這樣做例子給你當你去編譯它? –

+0

(錯誤] PLS-00630(1:12):PLS-00630:流水線函數必須具有受支持的收集返回類型 [錯誤] PLS-00382(10:22):PLS-00382:表達式類型錯誤) 但我只是爲了一個例子而寫的,我不能添加所有我試過的例子 – Deniz

回答

1

您的代碼有兩個語法錯誤和一個邏輯錯誤。

第一個語法錯誤是函數的返回類型應該是一個集合而不是行類型,所以

return t2_tab pipelined 

第二個語法錯誤是,你需要包括的類型實例化一個對象時,和參數的數量必須與類型的簽名匹配。所以外環分配應該是:

l_row2(i) := t2_row(i, 'T2', l_row1); 

的邏輯錯誤是,我們不需要保持輸出的集合變量。我們只需要一個行變量。

此外,索引計數似乎有點混亂,所以我的代碼可能與您的意圖不同。

create or replace function fn (r in number) 
    return t2_tab pipelined 
is 
    l_tab1 t1_tab; 
    l_row2 t2_row; 
begin 
    for i in 1..r loop    
     l_tab1 := new t1_tab(); 
     l_tab1.extend(r); 
     for j in 1..r loop 
      l_tab1(j) := t1_row(j*i, 'a2 ' || j); 
     end loop; 
     l_row2 := t2_row(i, 'T2', l_tab1); 
     PIPE ROW (l_row2); 
    end loop; 
    return; 
end; 
/

這裏是運行:

SQL> select * from table(fn(3)); 

    B1 B2 B3(A1, A2) 
----- --- --------------------------------------------------------------- 
    1 T2 T1_TAB(T1_ROW(1, 'a2 1'), T1_ROW(2, 'a2 2'), T1_ROW(3, 'a2 3')) 
    2 T2 T1_TAB(T1_ROW(2, 'a2 1'), T1_ROW(4, 'a2 2'), T1_ROW(6, 'a2 3')) 
    3 T2 T1_TAB(T1_ROW(3, 'a2 1'), T1_ROW(6, 'a2 2'), T1_ROW(9, 'a2 3')) 

SQL> 
2

你建設t2_row缺少第二個參數,你是 返回錯誤的類型。試試這個:

create or replace function fn (r in number) return t2_tab pipelined is 
    l_row1 t1_tab := t1_tab(); 
    l_row2 t2_tab := t2_tab(); 
begin 
    for i in 1..r loop    
     for j in 1..r loop 
      l_row1.extend(1); 
      l_row1(j) := t1_row(j,'a2 ' || j); 
     end loop; 
     l_row2.extend(1); 
     l_row2(i) := t2_row(i,'TEST',l_row1); 
     PIPE ROW (l_row2(i)); 
    end loop; 
    return; 
end; 

此外,閱讀如何使用PL/SQL對象集合this tutorial

+0

這給出了:ORA-06531:引用未初始化的集合 – Deniz

+0

更正的示例。 – OldProgrammer

+0

非常感謝你這個代碼也可以工作,現在我知道該怎麼做 – Deniz