有没有一种方法可以在Oracle apex中显示动态列

时间:2019-09-12 07:44:13

标签: plsql oracle11g oracle-apex-5.1

长话短说,由于我需要在各列中添加较长的元素,因此我无法使用数据透视。尽管我尝试根据Oracle Apex中的功能创建经典报表。该查询已正确生成,但在经典报表中不起作用。

ServerError

当我发现构建动态列时,问题应该在这一行。

function supportReport (
    p_start    in  c_checkin.date_registered%type,
    p_end      in  c_checkin.date_registered%type,
    p_country  in  user_table.timesheet_country%type
) return varchar2
is
    lt_cust    cust_name_tt;

    l_sql    varchar2(32767) := '';
begin
    select 
        distinct kc.customer_name as customer
    bulk collect into lt_cust
    from koll_customers kc
    inner join c_support cs
        on kc.id = cs.client_id
    inner join c_checkin cc
        on cs.record_id = cc.id
    inner join user_table ku
        on upper(cc.employee_id) = upper(ku.username)
    where kc.end_date is null
        and cc.date_registered between to_date(p_start) and to_date(p_end)
        and ku.timesheet_country = p_country;


    if lt_cust.count > 0 then
        l_sql := q'[ select (ku.lastname||' '||ku.firstname) as name ]';
        for i in lt_cust.first .. lt_cust.last loop
            l_sql := l_sql || ' ,sum(DECODE(kc.customer_name, '''||lt_cust(i)||''', cs.number_of_hours)) as '|| '"' || lt_cust(i)|| '"' ||' ';
        end loop;
        l_sql := l_sql || ' from koll_customers kc
                            inner join c_support cs
                                on kc.id = cs.client_id
                            inner join c_checkin cc
                                on cs.record_id = cc.id
                            inner join user_table ku
                                on upper(cc.employee_id) = upper(ku.username)
                            where kc.end_date is null
                                and cc.date_registered between to_date('||''''||to_date(p_start)||''''||',''dd-mm-yyyy'') and to_date('||''''||to_date(p_end)||''''||',''dd-mm-yyyy'')
                                and ku.timesheet_country = '||p_country||'
                            group by (ku.lastname||'' ''||ku.firstname);';
    end if;

    return l_sql;
end;

如果“通用列”设置为“是”,它将获取我的数据,但我不知道每个列代表什么。 列显示如下:

  

col1,col2,col3,...,col60

这令人困惑,因为我不知道每一列代表什么。

任何建议都会对我有帮助,谢谢!

1 个答案:

答案 0 :(得分:1)

首先提供一般提示:使用l_sql将变量dbms_output.put_line输出到控制台,或使用某种调试表将其插入其中。也要注意该变量的数据类型。如果您需要扩展SQL,则可以达到需要使用CLOB变量而不是varchar2的地步。

如果您想完全分析问题,则需要提供表结构和测试数据,因此,我首先会向您提供一些一般性解释:

enter image description here

如果您的列数永久不变,则

Use Generic Column Names是可以的。但是,如果列的顺序甚至数量可以更改,那么这是个坏主意,因为如果查询的列数超过Generic Column Count

,则页面将显示错误

选项1:在查询中使用列别名

以输出详细显示名称的方式增强PL/SQL Function Body returning SQL Query,如下所示:

return 'select 1 as "Your verbose column name", 2 as "Column #2", 3 as "Column #3" from dual';

看起来像这样:

enter image description here

其缺点是列名也以这种方式出现在设计器中,并且APEX仅在您重新验证功能时才更新这些列名。您将很难在流程代码或动态操作中引用内部名称为Your verbose column name的列。

enter image description here

但是,即使您在不告知APEX的情况下更改列名(例如,将PL/SQL Function Body外部化为实函数),它仍然有效。

选项2:使用自定义列标题

有点隐藏,但是还可以选择完全自定义的列标题。它几乎在报告区域的属性页面的结尾。

enter image description here

在这里,您还可以提供一个返回列名的函数。请注意,此函数不应返回本身返回列名的SQL查询,而应返回由冒号分隔的列名。

enter image description here

使用这种方法,可以更轻松地在设计器中标识和引用您的列:

enter image description here

选项3:两者

关闭通用列名,让您的查询返回易于识别和引用的列名,并使用custom column headings函数为用户返回详细名称。

我的个人观点

我在生产应用程序中使用第三个选项,人们可以使用报表页面上的穿梭项目自己更改列的数量和顺序。花了一些时间,但现在它就像一种魅力一样,就像一些动态PIVOT而没有PIVOT