我正在构建一个报告,该报告应该根据请求的年份(即 2000 到 2002 年)生成动态列列表。用户应该能够通过SELECT
如下语句运行报告:
SELECT * FROM TABLE(myreport(2002, 3)); -- Get 3 report years starting with 2002
目前,我有一个生成此输出的表函数,但具有静态列名:
-- Row type
CREATE OR REPLACE TYPE typ_myreport AS OBJECT (
myuser VARCHAR(260),
yr1_p DECIMAL(5,2),
yr1_t INTEGER,
yr2_p DECIMAL(5,2),
yr2_t INTEGER,
...
);
-- Table type
CREATE OR REPLACE TYPE tab_myreport AS TABLE OF typ_myreport;
-- Report
CREATE OR REPLACE FUNCTION myreport(pAsOfYear IN INTEGER)
RETURN tab_myreport PIPELINED AS
BEGIN
FOR vRec IN (
SELECT user_name, yr1_p, yr1_t, y2_p, y2_t, ...
FROM mytable
)
LOOP
PIPE ROW (
typ_myreport(vRec.user_name, vRec.yr1_p, vRec.yr1_t, vRec.yr2_p, vRec.year2_t, ...)
);
END LOOP;
RETURN;
END;
它产生如下输出:
User yr1_p yr1_t yr2_p yr2_t yr3_p yr3_t
-----------------------------------------------------
Bobby 25 2 33 2 20 4
Barry 50 4 66 4 50 10
Big Ben 25 2 0 0 30 6
但我希望根据请求的年份动态命名列:
User 2000_p 2000_t 2001_p 2001_t 2002_p 2002_t
------------------------------------------------------
Bobby 25 2 33 2 20 4
Barry 50 4 66 4 50 10
Big Ben 25 2 0 0 30 6
输出结果集应该保持完全相同——表结构、数据类型——只是列名应该改变。我的想法是通过一个动态构建的语句来做到这一点SELECT
,我可以执行它然后返回结果。我摸索着试图让它工作,但没有运气。
有没有办法在具有动态列数和列名的函数/过程中编写动态 SQL,然后将该结果集作为表(而不是脚本)输出返回?
更新
这里是生成yr
字段的实际查询的简化片段:
WITH rpt_years AS (SELECT * FROM TABLE(GetReportyears(pAsOfYear)))
SELECT user_name,
SUM(year1_cnt) AS yr1_t,
SUM(COALESCE((year1_cnt / NULLIF(year1_tot,0)),0)) AS yr1_p,
SUM(year2_cnt) AS yr2_t,
SUM(COALESCE((year2_cnt / NULLIF(year2_tot,0)),0)) AS yr2_p,
...
FROM (
SELECT DISTINCT
ui.user_name,
SUM(CASE WHEN s.dist_year = y.year1 THEN 1 END) AS year1_cnt,
COUNT(CASE WHEN s.dist_year = y.year1 THEN 1 END) AS year1_tot,
SUM(CASE WHEN s.dist_year = y.year2 THEN 1 END) AS year2_cnt,
COUNT(CASE WHEN s.dist_year = y.year2 THEN 1 END) AS year2_tot,
...
FROM rpt_years y -- Get report years as single row
INNER JOIN src_table s
...
) src
ORDER BY src.user_name