テーブルのピボットを解除したいようです (ピボットには、多数の行と 2 列から多数の列を持つ 1 行への移行が含まれます)。ほとんどの場合、動的 SQL を使用してクエリを生成し、DBMS_SQL
パッケージ (または場合によってはEXECUTE IMMEDIATE
) を使用して実行する必要があります。アンピボットを行ったパイプライン化されたテーブル関数を構築することもできるはずです。パイプライン化されたテーブル関数内でも動的 SQL を使用する必要がありますが、コードが少なくなる可能性があります。ただし、純粋な動的 SQL ステートメントを使用UNPIVOT
すると、より効率的であることが期待されます。
非効率的なアプローチですが、比較的簡単に実行できるアプローチは、次のようなものです。
SQL> ed
Wrote file afiedt.buf
1 create or replace type emp_unpivot_type
2 as object (
3 empno number,
4 col varchar2(4000)
5* );
SQL> /
Type created.
SQL> create or replace type emp_unpivot_tbl
2 as table of emp_unpivot_type;
3 /
Type created.
SQL> ed
Wrote file afiedt.buf
1 create or replace function unpivot_emp
2 ( p_empno in number )
3 return emp_unpivot_tbl
4 pipelined
5 is
6 l_val varchar2(4000);
7 begin
8 for cols in (select column_name from user_tab_columns where table_name = 'EMP')
9 loop
10 execute immediate 'select ' || cols.column_name || ' from emp where empno = :empno'
11 into l_val
12 using p_empno;
13 pipe row( emp_unpivot_type( p_empno, l_val ));
14 end loop;
15 return;
16* end;
SQL> /
Function created.
次に、SQLステートメントでそれを呼び出すことができます(列名を持つ少なくとも3番目の列が必要だと思います)
SQL> ed
Wrote file afiedt.buf
1 select *
2* from table( unpivot_emp( 7934 ))
SQL> /
EMPNO COL
---------- ----------------------------------------
7934 7934
7934 MILLER
7934 CLERK
7934 7782
7934 23-JAN-82
7934 1301
7934
7934 10
8 rows selected.
より効率的なアプローチは、Tom Kyte のshow_table パイプライン テーブル関数を採用することです。