Vì bạn không biết trước cấu trúc, do xoay vòng động đến một số cột không xác định trong tập kết quả, bạn có thể sử dụng con trỏ tham chiếu để truy xuất kết quả của truy vấn động.
Điều này sử dụng các biến liên kết 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 rc refcursor;
khai báo biến và kiểu dữ liệu của biến liên kết máy khách, như một con trỏ tham chiếu. Sau đó, thay vì sử dụng execute immediate
nó có mở cho với câu lệnh động của bạn:
open :rc for sql_stmt;
mở con trỏ tham chiếu với kết quả của truy vấn đó. (Lưu ý :
ở đầu :rc
, chỉ ra rằng đó là một tham chiếu biến ràng buộc không phải là một biến PL / SQL cục bộ).
Sau đó, bên ngoài khối, bạn có thể in kết quả được đặt với:
print rc
Các máy khách / IDE khác nhau sẽ cần các cú pháp khác nhau. Bạn cũng có thể làm điều gì đó tương tự trên JDBC. Bạn cũng có thể có một hàm trả về sys_refcursor
. Nhưng nó phụ thuộc vào mục tiêu cuối cùng của bạn cho việc này là gì.
Ngẫu nhiên, tại thời điểm này, bạn sẽ nhận được null cho tất cả các tổng xoay vòng; truy vấn cuối cùng của bạn cần lấy PERIOD_NAME
ở cùng một định dạng mà mệnh đề xoay đang tìm kiếm, ví dụ:
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 || '))';
mặc dù sẽ đơn giản hơn một chút nếu để định dạng ban đầu trong mệnh đề xoay thay thế:
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;
/
Với một bảng giả và dữ liệu:
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;
đang chạy một trong hai phiên bản và thực hiện print rc
cho thấy:
JAN-18 FEB-18 MAR-18
---------- ---------- ----------
42 11 99