Тъй като не знаете структурата предварително, поради динамичното завъртане към неизвестен брой колони в набора от резултати, можете да използвате референтен курсор, за да извлечете резултата от динамичната заявка.
Това използва променливи за свързване SQL*Plus/SQL Developer/SQLcl;
variable rc refcursor;
declare
sql_stmt clob;
pivot_clause clob;
begin
select listagg('''' || TO_CHAR(PERIOD_NAME,'MON-YY') || ''' as "' || TO_CHAR(PERIOD_NAME,'MON-YY') || '"', ',')
within group (order by PERIOD_NAME)
into pivot_clause from (select TO_DATE(PERIOD_NAME,'MON-YYYY') PERIOD_NAME
from table1
where request_id=<id>
GROUP BY TO_DATE(PERIOD_NAME,'MON-YYYY')
order by TO_DATE(PERIOD_NAME,'MON-YYYY') ASC);
sql_stmt := 'select * from (select PERIOD_NAME, depreciation
from table1) pivot (sum(depreciation) for PERIOD_NAME in (' || pivot_clause || '))';
open :rc for sql_stmt;
end;
/
print rc
variable rc refcursor;
декларира променливата и типа данни на променливата за свързване на клиента като референтен курсор. След това вместо да използвате execute immediate
той отворен за с вашето динамично изявление:
open :rc for sql_stmt;
който отваря ref курсора с резултатите от тази заявка. (Забележете :
в началото на :rc
, което показва, че е препратка към променлива за свързване, а не към локална PL/SQL променлива).
След това извън блока можете да отпечатате наборът от резултати с:
print rc
Различните клиенти/IDE ще се нуждаят от различен синтаксис. Бихте могли да направите нещо подобно и върху JDBC. Можете също да имате функция, която връща sys_refcursor
. Но зависи каква е крайната ви цел за това.
Между другото, в момента ще получите нула за всички обобщени суми; последната ви заявка трябва да получи PERIOD_NAME
в същия формат, който търси централната клауза, напр.
sql_stmt := 'select * from (select to_char(to_date(PERIOD_NAME, ''MON-YYYY''), ''MON-YY'') as PERIOD_NAME, depreciation
from table1) pivot (sum(depreciation) for PERIOD_NAME in (' || pivot_clause || '))';
въпреки че би било малко по-лесно вместо това да оставите оригиналния формат в осевата клауза:
declare
sql_stmt clob;
pivot_clause clob;
begin
select listagg('''' || PERIOD_NAME || ''' as "' || TO_CHAR(PERIOD_DATE,'MON-YY') || '"', ',')
within group (order by PERIOD_DATE)
into pivot_clause from (select distinct PERIOD_NAME, TO_DATE(PERIOD_NAME,'MON-YYYY') PERIOD_DATE
from table1
where request_id=<id>);
sql_stmt := 'select * from (select PERIOD_NAME, depreciation
from table1) pivot (sum(depreciation) for PERIOD_NAME in (' || pivot_clause || '))';
open :rc for sql_stmt;
end;
/
С фиктивна таблица и данни:
create table table1 (request_id, period_name, depreciation) as
select 1, 'JAN-2018', 42 from dual
union all select 1, 'FEB-2018', 11 from dual
union all select 1, 'MAR-2018', 22 from dual
union all select 1, 'MAR-2018', 33 from dual
union all select 2, 'MAR-2018', 44 from dual;
изпълнява всяка версия и прави print rc
показва:
JAN-18 FEB-18 MAR-18
---------- ---------- ----------
42 11 99