Звучи сякаш искате да отмените завъртането на таблицата (завъртането ще включва преминаване от много редове и 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 израз (мисля, че бихте искали поне трета колона с името на колоната)
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.
По-ефективен подход би бил да се адаптира функцията за конвейерна таблица show_table на Tom Kyte.