管道嵌套对象类型
Pipe nested object type
我只是想实现管道行嵌套类型。周围有很多例子,但 none 我可以应用。
我的类型是:
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;
我尝试了很多方法来创建一个函数,但是 none 能够成功编译。
一个例子:
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;
此代码产生以下错误:
[Error] PLS-00630 (1: 12): PLS-00630: pipelined functions must have a supported collection return type
[Error] PLS-00382 (10: 22): PLS-00382: expression is of wrong type
任何帮助建议或任何类似示例都可能有用。
版本:Oracle 11g 11.2.0.1.0 版
你对 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;
此外,阅读 this tutorial 如何使用 pl/sql 对象集合。
您的代码有两个语法错误和一个逻辑错误。
第一个语法错误是函数的 return 类型应该是集合而不是行类型,所以
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>
我只是想实现管道行嵌套类型。周围有很多例子,但 none 我可以应用。
我的类型是:
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;
我尝试了很多方法来创建一个函数,但是 none 能够成功编译。
一个例子:
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;
此代码产生以下错误:
[Error] PLS-00630 (1: 12): PLS-00630: pipelined functions must have a supported collection return type
[Error] PLS-00382 (10: 22): PLS-00382: expression is of wrong type
任何帮助建议或任何类似示例都可能有用。
版本:Oracle 11g 11.2.0.1.0 版
你对 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;
此外,阅读 this tutorial 如何使用 pl/sql 对象集合。
您的代码有两个语法错误和一个逻辑错误。
第一个语法错误是函数的 return 类型应该是集合而不是行类型,所以
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>