在 Oracle APEX Interactive Report 中根据过滤器更新页面项
Updating Page Items with Respect to Filters in Oracle APEX Interactive Report
我最近开始在我的 Oracle APEX 应用程序中使用交互式报告。以前,应用程序中的所有页面都使用经典报表。我的新页面中的交互式报告效果很好,但是现在,我想在同一页面上的交互式报告上方添加一个摘要 box/table,以显示交互式报告中某些列的总和值。换句话说,如果我的交互式报表显示 3 个不同的经理姓名、2 个不同的办公地点和 5 个不同的员工,我的摘要框将包含一行和三列,数字分别为 3、2 和 5。
到目前为止,我已经通过将摘要框创建为经典报表来完成这项工作,该报表计算我的交互式报表所从中提取的同一 table 中每一列的不同值。当我尝试过滤交互式报告时出现问题。显然,经典报告不会根据交互式报告过滤器进行刷新,但我不知道如何 link 这两者,以便经典报告响应交互式报告中的过滤器。根据我的研究,有一些方法可以使用 javascript/jquery 来引用交互式报表搜索框中的值。如果可能,我想使用 javascript 或 jquery 引用交互式 table 过滤器的值,以便在每次应用新过滤器时刷新摘要框。有人知道怎么做吗?
不要对过滤器进行 javascript 解析。这是一个坏主意 - 想想你将如何实现它?有大量的编码工作要做,还有很多 ajax。随着 apex 5 的临近,当 API 和标记即将发生巨大变化时,它会把你留在哪里?
也不要只是屈服于要求。首先确定它在技术上的可行性。如果不是,请确保您非常清楚这对时间消耗的影响。拥有这些不同的价值计数的真正价值是什么?也许还有另一种方法可以实现他们想要的?也许这只不过是一种尝试性的解决方案,而不是真正问题的核心。需要考虑的事情...
话虽如此,这里有 2 个选项:
第一种方法:计算交互式报表上的不同聚合数
您可以通过“操作”按钮将这些添加到 IR。
不过请注意,这个聚合将是最后一行!在我在这里发布的示例中,将每页的行数减少到 5 会将聚合行推到分页集 3!
第二种方法:APEX_IR和DBMS_SQL
您可以使用 apex_ir API 检索 IR 的查询,然后使用它来进行计数。
(Apex 4.2) APEX_IR.GET_REPORT
(Apex 5.0) APEX_IR.GET_REPORT
一些建议:
通过查询 apex_application_page_regions
检索区域 ID
确保您的源查询不包含#...#
替换字符串。 (比如#OWNER#
。)
然后获取报告SQL,重写并执行。例如:
DECLARE
l_report apex_ir.t_report;
l_query varchar2(32767);
l_statement varchar2(32000);
l_cursor integer;
l_rows number;
l_deptno number;
l_mgr number;
BEGIN
l_report := APEX_IR.GET_REPORT (
p_page_id => 30,
p_region_id => 63612660707108658284,
p_report_id => null);
l_query := l_report.sql_query;
sys.htp.prn('Statement = '||l_report.sql_query);
for i in 1..l_report.binds.count
loop
sys.htp.prn(i||'. '||l_report.binds(i).name||' = '||l_report.binds(i).value);
end loop;
l_statement := 'select count (distinct deptno), count(distinct mgr) from ('||l_report.sql_query||')';
sys.htp.prn('statement rewrite: '||l_statement);
l_cursor := dbms_sql.open_cursor;
dbms_sql.parse(l_cursor, l_statement, dbms_sql.native);
for i in 1..l_report.binds.count
loop
dbms_sql.bind_variable(l_cursor, l_report.binds(i).name, l_report.binds(i).value);
end loop;
dbms_sql.define_column(l_cursor, 1, l_deptno);
dbms_sql.define_column(l_cursor, 2, l_mgr);
l_rows := dbms_sql.execute_and_fetch(l_cursor);
dbms_sql.column_value(l_cursor, 1, l_deptno);
dbms_sql.column_value(l_cursor, 2, l_mgr);
dbms_sql.close_cursor(l_cursor);
sys.htp.prn('Distinct deptno: '||l_deptno);
sys.htp.prn('Distinct mgr: '||l_mgr);
EXCEPTION WHEN OTHERS THEN
IF DBMS_SQL.IS_OPEN(l_cursor) THEN
DBMS_SQL.CLOSE_CURSOR(l_cursor);
END IF;
RAISE;
END;
我将 apex_ir.get_report 和 dbms_sql 中的示例代码放在一起。
Oracle 11gR2 DBMS_SQL reference
但有一些严重的警告:列列表很棘手。如果用户可以控制所有列并且可以删除一些列,那么这些列将从 select 列表中消失。例如,在我的示例中,让用户隐藏 DEPTNO 列会导致整个代码崩溃,因为即使它会从内部查询中消失,我仍然会对该列进行计数。您可以通过不让用户控制它或首先解析语句等来阻止它...
祝你好运。
我最近开始在我的 Oracle APEX 应用程序中使用交互式报告。以前,应用程序中的所有页面都使用经典报表。我的新页面中的交互式报告效果很好,但是现在,我想在同一页面上的交互式报告上方添加一个摘要 box/table,以显示交互式报告中某些列的总和值。换句话说,如果我的交互式报表显示 3 个不同的经理姓名、2 个不同的办公地点和 5 个不同的员工,我的摘要框将包含一行和三列,数字分别为 3、2 和 5。
到目前为止,我已经通过将摘要框创建为经典报表来完成这项工作,该报表计算我的交互式报表所从中提取的同一 table 中每一列的不同值。当我尝试过滤交互式报告时出现问题。显然,经典报告不会根据交互式报告过滤器进行刷新,但我不知道如何 link 这两者,以便经典报告响应交互式报告中的过滤器。根据我的研究,有一些方法可以使用 javascript/jquery 来引用交互式报表搜索框中的值。如果可能,我想使用 javascript 或 jquery 引用交互式 table 过滤器的值,以便在每次应用新过滤器时刷新摘要框。有人知道怎么做吗?
不要对过滤器进行 javascript 解析。这是一个坏主意 - 想想你将如何实现它?有大量的编码工作要做,还有很多 ajax。随着 apex 5 的临近,当 API 和标记即将发生巨大变化时,它会把你留在哪里?
也不要只是屈服于要求。首先确定它在技术上的可行性。如果不是,请确保您非常清楚这对时间消耗的影响。拥有这些不同的价值计数的真正价值是什么?也许还有另一种方法可以实现他们想要的?也许这只不过是一种尝试性的解决方案,而不是真正问题的核心。需要考虑的事情...
话虽如此,这里有 2 个选项:
第一种方法:计算交互式报表上的不同聚合数
您可以通过“操作”按钮将这些添加到 IR。
不过请注意,这个聚合将是最后一行!在我在这里发布的示例中,将每页的行数减少到 5 会将聚合行推到分页集 3!
第二种方法:APEX_IR和DBMS_SQL
您可以使用 apex_ir API 检索 IR 的查询,然后使用它来进行计数。
(Apex 4.2) APEX_IR.GET_REPORT
(Apex 5.0) APEX_IR.GET_REPORT
一些建议: 通过查询 apex_application_page_regions
检索区域 ID确保您的源查询不包含#...#
替换字符串。 (比如#OWNER#
。)
然后获取报告SQL,重写并执行。例如:
DECLARE
l_report apex_ir.t_report;
l_query varchar2(32767);
l_statement varchar2(32000);
l_cursor integer;
l_rows number;
l_deptno number;
l_mgr number;
BEGIN
l_report := APEX_IR.GET_REPORT (
p_page_id => 30,
p_region_id => 63612660707108658284,
p_report_id => null);
l_query := l_report.sql_query;
sys.htp.prn('Statement = '||l_report.sql_query);
for i in 1..l_report.binds.count
loop
sys.htp.prn(i||'. '||l_report.binds(i).name||' = '||l_report.binds(i).value);
end loop;
l_statement := 'select count (distinct deptno), count(distinct mgr) from ('||l_report.sql_query||')';
sys.htp.prn('statement rewrite: '||l_statement);
l_cursor := dbms_sql.open_cursor;
dbms_sql.parse(l_cursor, l_statement, dbms_sql.native);
for i in 1..l_report.binds.count
loop
dbms_sql.bind_variable(l_cursor, l_report.binds(i).name, l_report.binds(i).value);
end loop;
dbms_sql.define_column(l_cursor, 1, l_deptno);
dbms_sql.define_column(l_cursor, 2, l_mgr);
l_rows := dbms_sql.execute_and_fetch(l_cursor);
dbms_sql.column_value(l_cursor, 1, l_deptno);
dbms_sql.column_value(l_cursor, 2, l_mgr);
dbms_sql.close_cursor(l_cursor);
sys.htp.prn('Distinct deptno: '||l_deptno);
sys.htp.prn('Distinct mgr: '||l_mgr);
EXCEPTION WHEN OTHERS THEN
IF DBMS_SQL.IS_OPEN(l_cursor) THEN
DBMS_SQL.CLOSE_CURSOR(l_cursor);
END IF;
RAISE;
END;
我将 apex_ir.get_report 和 dbms_sql 中的示例代码放在一起。
Oracle 11gR2 DBMS_SQL reference
但有一些严重的警告:列列表很棘手。如果用户可以控制所有列并且可以删除一些列,那么这些列将从 select 列表中消失。例如,在我的示例中,让用户隐藏 DEPTNO 列会导致整个代码崩溃,因为即使它会从内部查询中消失,我仍然会对该列进行计数。您可以通过不让用户控制它或首先解析语句等来阻止它...
祝你好运。