sql >> Databasteknik >  >> RDS >> Oracle

exekvera omedelbart utan att visa poster av Dynamic Select-satsen

Eftersom du inte känner till strukturen i förväg, på grund av den dynamiska pivoten till ett okänt antal kolumner i resultatuppsättningen, kan du använda en ref-markör för att hämta resultatet av den dynamiska frågan.

Detta använder SQL*Plus/SQL Developer/SQLcl bindningsvariabler;

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

klient-variable kommando

variable rc refcursor;

deklarerar variabeln och datatypen för klientbindningsvariabeln, som en referensmarkör. Sedan istället för att använda execute immediate den är öppen för med ditt dynamiska uttalande:

  open :rc for sql_stmt; 

som öppnar ref-markören med resultaten av den frågan. (Lägg märke till : i början av :rc , vilket indikerar att det är en bindningsvariabelreferens inte en lokal PL/SQL-variabel).

Sedan utanför blocket kan du skriva ut resultatuppsättningen med:

print rc

Olika klienter/IDE:er kommer att behöva olika syntax. Du kan göra något liknande över JDBC också. Du kan också ha en funktion som returnerar en sys_refcursor . Men det beror på vad ditt slutmål för detta är.

För övrigt, för tillfället får du null för alla pivoterade summor; din sista fråga måste få PERIOD_NAME i samma format som pivotsatsen letar efter, t.ex.

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

även om det skulle vara något enklare att lämna originalformatet i pivotsatsen istället:

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

Med en dummy-tabell och data:

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;

kör endera versionen och gör print rc visar:

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


  1. Automatiserad testning av skrivbordsapplikationen:översikt över ändamålsenlighet och ramverk

  2. Att markera en cell PHP en viss färg baserat på MYSQL-värde

  3. MySQL Connector för Python

  4. 4 sätt att välja dubbletter av rader i PostgreSQL