Oracle
 sql >> Baza danych >  >> RDS >> Oracle

wykonaj natychmiastowe niepokazywanie rekordów instrukcji Dynamic Select

Ponieważ nie znasz z góry struktury, z powodu dynamicznego przestawiania do nieznanej liczby kolumn w zestawie wyników możesz użyć kursora ref, aby pobrać wynik dynamicznego zapytania.

To używa zmiennych wiązania 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

variable klienta polecenie

variable rc refcursor;

deklaruje zmienną i typ danych zmiennej wiążącej klienta jako kursor referencyjny. Wtedy zamiast używać execute immediate to otwarte dla za pomocą dynamicznego zestawienia:

  open :rc for sql_stmt; 

który otwiera kursor ref z wynikami tego zapytania. (Zwróć uwagę na : na początku :rc , wskazując, że jest to odwołanie do zmiennej wiążącej, a nie lokalna zmienna PL/SQL).

Następnie poza blokiem możesz wydrukować zestaw wyników z:

print rc

Różni klienci/IDE będą potrzebować innej składni. Możesz też zrobić coś podobnego w JDBC. Możesz także mieć funkcję, która zwraca sys_refcursor . Ale to zależy od tego, jaki jest Twój ostateczny cel.

Nawiasem mówiąc, w tej chwili uzyskasz wartość null dla wszystkich przestawianych sum; Twoje ostatnie zapytanie musi uzyskać PERIOD_NAME w tym samym formacie, którego szuka klauzula pivot, np.

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

chociaż nieco prościej byłoby pozostawić oryginalny format w klauzuli pivot:

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

Z fikcyjną tabelą i danymi:

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;

uruchamianie dowolnej wersji i wykonywanie print rc pokazuje:

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


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Funkcja NVL2 w Oracle

  2. Pobierz wyjątek SQLException java.sql.SQLException:ResultSet.next nie został wywołany

  3. Jak rozwiązać ORA-00939:zbyt wiele argumentów dla błędu funkcji?

  4. Jak używać parametrów SQL w fragmencie SQL przeceny języka R?

  5. Zaawansowane kolejkowanie Oracle z .Net