我正在尝试整理一些 PL/SQL 代码,尝试测试性能。能够做到这一点将使我们减少对数据库的调用,但我不确定如何填充我创建的返回类型。这是一个设计不佳的表结构,它展示了我想要完成的工作。
create table emp_group (
gid number,
gname varchar2(10)
);
create table emp (
empID number,
gid number,
empname varchar2(10)
);
create or replace type t_emp_obj as object (
empID number,
gid number,
empname varchar2(10)
);
create or replace type t_emp is table of t_emp_obj;
create or replace type t_group_emp as object
(
gid number,
gname varchar2(10),
g_emps t_emp
);
insert into emp( empID, gid, empName ) values ( 1, 10, 'Rob' );
insert into emp( empID, gid, empName ) values ( 2, 10, 'Ken' );
insert into emp( empID, gid, empName ) values ( 3, 10, 'Dave' );
insert into emp( empID, gid, empName ) values ( 4, 10, 'Ron' );
insert into emp( empID, gid, empName ) values ( 5, 11, 'Joe' );
insert into emp_group( gid, gname ) values (10, 'DDP');
insert into emp_group( gid, gname ) values (11, 'DDD');
commit;
create or replace function f_test1 return t_emp as
ret t_emp;
begin
select t_emp_obj(empID, gid, empname) bulk collect into ret from emp;
return ret;
end;
create or replace function f_test2 return t_group_emp as
ret t_group_emp;
begin
select t_group_emp(????) bulk collect into ret
from emp, emp_group
where emp.gid = emp_group.gid;
return ret;
end;
这是一个运行它的函数。
set serveroutput on size 10000
declare
x t_emp;
begin
x := f_test1;
for r in (select * from table(cast(x as t_emp))) loop
dbms_output.put_line(r.empID || ', ' || r.gid || ', ' || r.empname );
end loop;
end;
我们有两张表,一张是员工列表,一张是员工组列表。忽略 emp_group 和 emp 之间应该有一个连接表这样一个员工可以属于多个组的事实......演示代码。8)
我想以单个返回类型返回给定组 ID 的所有员工以及组行。返回的类型是 t_group_emp,它有一个 emp 行表。f_test2 的语法是什么?
1)这可能吗?
2) 我将如何构造 select 语句来填充返回的类型?在这里“批量收集”是正确的方法吗?我发现这个页面是一个很好的起点。
3)这会表现得有多差?对语法进行排序后,我可以运行自己的数字,但总的来说,这是从具有 1-N 关系的多个表返回数据的好方法吗?
编写应用程序以使用返回的类型很容易,所以我并不担心。
编辑:我们正在使用 Oracle 10.3.something ...
编辑:这接近我想要的,但不完全是。
create or replace
function f_test2 return t_group as
ret t_group;
begin
select t_group_emp( emp_group.gid, emp_group.gname, t_emp( t_emp_obj( emp.empID, emp.gid, emp.empName ))) bulk collect into ret
from emp, emp_group
where emp.gid = emp_group.gid;
return ret;
end;
以及一个贯穿那个的函数......
set serveroutput on size 10000
declare
x t_group;
begin
x := f_test2;
for r in (select * from table(cast(x as t_group))) loop
dbms_output.put_line( 'group ' || r.gid || ', ' || r.gname );
for s in (select * from table(cast(r.g_emps as t_emp))) loop
dbms_output.put_line( 'emp ' || s.empID || ', ' || s.empname );
end loop;
end loop;
end;
给出以下输出:
group 10, DDP
emp 1, Rob
group 10, DDP
emp 2, Ken
group 10, DDP
emp 3, Dave
group 10, DDP
emp 4, Ron
group 11, DDD
emp 5, Joe
这很好,但我希望输出看起来像这样,以显示 1-N 关系。
group 10, DDP
emp 1, Rob
emp 2, Ken
emp 3, Dave
emp 4, Ron
group 11, DDD
emp 5, Joe
我需要在 f_test2 函数中更改什么来实现这一点?