sql >> Database >  >> RDS >> Oracle

onmiddellijk uitvoeren zonder records van Dynamic Select-instructie weer te geven

Omdat u de structuur niet van tevoren kent, vanwege de dynamische spil naar een onbekend aantal kolommen in de resultatenset, kunt u een ref-cursor gebruiken om het resultaat van de dynamische query op te halen.

Dit maakt gebruik van SQL*Plus/SQL Developer/SQLcl-bindvariabelen;

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

De client variable commando

variable rc refcursor;

declareert de variabele en het gegevenstype van de client-bindvariabele als een referentiecursor. In plaats van execute immediate . te gebruiken het doet open voor met uw dynamische verklaring:

  open :rc for sql_stmt; 

die de ref-cursor opent met de resultaten van die zoekopdracht. (Let op de : aan het begin van :rc , wat aangeeft dat dit een verwijzing naar een bindvariabele is en geen lokale PL/SQL-variabele).

Buiten het blok kun je printen het resultaat is ingesteld met:

print rc

Verschillende clients/IDE's hebben een andere syntaxis nodig. Je zou iets soortgelijks ook via JDBC kunnen doen. Je zou ook een functie kunnen hebben die een sys_refcursor . teruggeeft . Maar het hangt ervan af wat je einddoel hiervoor is.

Overigens krijg je op dit moment nul voor alle gedraaide totalen; je laatste zoekopdracht moet PERIOD_NAME . krijgen in hetzelfde formaat waarnaar de spilclausule zoekt, bijvoorbeeld

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

hoewel het iets eenvoudiger zou zijn om in plaats daarvan het originele formaat in de spilclausule te laten:

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

Met een dummytabel en gegevens:

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;

beide versies draaien en print rc . doen toont:

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


  1. Hoe paginering toe te voegen in php

  2. mysql:selecteren, invoegen, verwijderen en bijwerken in één query

  3. Hoe kan ik in SQL Server overal een kolom vinden waarnaar wordt verwezen?

  4. #1062 - Dubbele invoer voor sleutel 'PRIMARY'