sql >> Base de Datos >  >> RDS >> Oracle

ejecutar inmediatamente sin mostrar registros de instrucción Dynamic Select

Como no conoce la estructura de antemano, debido al pivote dinámico a un número desconocido de columnas en el conjunto de resultados, puede usar un cursor de referencia para recuperar el resultado de la consulta dinámica.

Esto utiliza variables de enlace 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

El cliente variable comando

variable rc refcursor;

declara la variable y el tipo de datos de la variable de vinculación del cliente, como un cursor de referencia. Luego, en lugar de usar execute immediate hace abrir para con su declaración dinámica:

  open :rc for sql_stmt; 

que abre el cursor de referencia con los resultados de esa consulta. (Observe el : al comienzo de :rc , lo que indica que es una referencia de variable de vinculación, no una variable PL/SQL local).

Luego, fuera del bloque, puede imprimir el conjunto de resultados con:

print rc

Diferentes clientes/IDE necesitarán una sintaxis diferente. También podría hacer algo similar con JDBC. También podría tener una función que devuelva un sys_refcursor . Pero depende de cuál sea tu objetivo final para esto.

Por cierto, en este momento obtendrá nulo para todos los totales pivotados; su consulta final debe obtener PERIOD_NAME en el mismo formato que busca la cláusula pivote, por ejemplo,

  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 || '))';

aunque sería un poco más simple dejar el formato original en la cláusula pivote:

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;
/

Con una tabla ficticia y datos:

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;

ejecutando cualquiera de las versiones y haciendo print rc muestra:

    JAN-18     FEB-18     MAR-18
---------- ---------- ----------
        42         11         99