Oracle
 sql >> Datenbank >  >> RDS >> Oracle

sofort ausführen, ohne Aufzeichnungen von Dynamic Select-Anweisungen anzuzeigen

Da Sie die Struktur aufgrund des dynamischen Pivots auf eine unbekannte Anzahl von Spalten in der Ergebnismenge nicht im Voraus kennen, könnten Sie einen Ref-Cursor verwenden, um das Ergebnis der dynamischen Abfrage abzurufen.

Dies verwendet SQL*Plus/SQL Developer/SQLcl-Bind-Variablen;

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

Die Client-variable Befehl

variable rc refcursor;

deklariert die Variable und den Datentyp der Client-Bind-Variablen als Referenz-Cursor. Dann anstatt execute immediate zu verwenden es macht offen für mit Ihrer dynamischen Aussage:

  open :rc for sql_stmt; 

wodurch der Ref-Cursor mit den Ergebnissen dieser Abfrage geöffnet wird. (Beachten Sie den : am Anfang von :rc , was darauf hinweist, dass es sich um eine Bind-Variablenreferenz und nicht um eine lokale PL/SQL-Variable handelt).

Dann können Sie außerhalb des Blocks drucken die Ergebnismenge mit:

print rc

Unterschiedliche Clients/IDEs benötigen unterschiedliche Syntax. Sie könnten etwas Ähnliches auch über JDBC tun. Sie könnten auch eine Funktion haben, die einen sys_refcursor zurückgibt . Aber es hängt davon ab, was Ihr Endziel dafür ist.

Im Moment erhalten Sie übrigens für alle Pivot-Summen null; Ihre letzte Abfrage muss PERIOD_NAME erhalten im selben Format, nach dem die Pivot-Klausel sucht, z. B.

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

obwohl es etwas einfacher wäre, stattdessen das ursprüngliche Format in der Pivot-Klausel zu belassen:

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

Mit einer Dummy-Tabelle und Daten:

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;

Führen Sie eine der beiden Versionen aus und führen Sie print rc aus zeigt:

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