Como você não conhece a estrutura antecipadamente, devido ao pivô dinâmico para um número desconhecido de colunas no conjunto de resultados, você pode usar um cursor ref para recuperar o resultado da consulta dinâmica.
Isso usa variáveis de ligação 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
A variável
variable
do cliente comando
variable rc refcursor;
declara a variável e o tipo de dados da variável de ligação do cliente, como um cursor de referência. Então, em vez de usar
execute immediate
ele abre para com sua declaração dinâmica: open :rc for sql_stmt;
que abre o cursor ref com os resultados dessa consulta. (Observe o
:
no início de :rc
, indicando que é uma referência de variável de ligação e não uma variável PL/SQL local). Então, fora do bloco, você pode imprimir o conjunto de resultados com:
print rc
Diferentes clientes/IDEs precisarão de sintaxe diferente. Você poderia fazer algo semelhante sobre JDBC também. Você também pode ter uma função que retorna um
sys_refcursor
. Mas depende de qual é o seu objetivo final para isso. Aliás, no momento você obterá null para todos os totais pivotados; sua consulta final precisa obter
PERIOD_NAME
no mesmo formato que a cláusula pivô está procurando, por exemplo 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 || '))';
embora seja um pouco mais simples deixar o formato original na cláusula pivô:
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;
/
Com uma tabela fictícia e dados:
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;
executando qualquer uma das versões e fazendo
print rc
mostra: JAN-18 FEB-18 MAR-18
---------- ---------- ----------
42 11 99