PL / SQLコードを整理し、パフォーマンスをテストしようとしています。これができると、DBの呼び出しを大幅に減らすことができますが、作成した返されたタイプを入力する方法がわかりません。これは、私が達成しようとしていることを示す、不十分に設計されたテーブル構造です。
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;
2つのテーブルがあります。1つは従業員のリストで、もう1つは従業員グループのリストです。従業員が複数のグループに属することができるように、emp_groupとempの間に結合テーブルが必要であるという事実を無視してください...デモコード。8)
特定のグループIDのすべての従業員を、グループ行とともに、単一の返されるタイプで返したいと思います。返されるタイプはt_group_empで、これにはemp行のテーブルがあります。f_test2の構文は何ですか?
1)これは可能ですか?
2)返されたタイプを埋めるためにselectステートメントをどのように構成しますか?ここで「一括収集」は正しい方法ですか?このページは良い出発点であることがわかりました。
3)これはどれほどうまく機能しませんか?構文を並べ替えると、自分の数値を実行できますが、全体として、これは1-Nの関係を持つ複数のテーブルからデータを返すための優れたアプローチですか?
返された型を使用するようにアプリケーションをコーディングするのは簡単なので、私はそれについて心配していません。
編集:Oracle10.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関数で何を変更する必要がありますか?