我正在构建一个Oracle ApEx页面来显示数据图表。数据作为输入输入到表中,但实际计算的度量可能会有所不同,具体取决于正在查看的KPI(AVG(VALUE_1); SUM(VALUE_1)/ SUM(VALUE_2);等等);这些计算存储在单独的表中。由于我希望所有内容都是动态的,因此我使用PL / SQL函数体的源代码返回SQL查询。这是一个简化版本
DECLARE
SQL_STMT VARCHAR2 (32767);
CALC_CLAUSE VARCHAR2 (4000);
BEGIN
SELECT CALCULATION
INTO CALC_CLAUSE
FROM KPI_TYPES
WHERE ID = 101;
--when the value itself is entered, the results display as intended
SQL_STMT := 'SELECT DATE, ' || CALC_CLAUSE || ' KPI_VALUE
FROM DATA_VALUES
WHERE TYPE_ID = :P_KPI
GROUP BY DATE';
RETURN SQL_STMT;
END;
如上所述,当手动输入KPI的ID时,这可以正常工作,但我希望这是动态的。我有一个选择列表页面项(P_KPI)供用户选择查看的KPI。它的值实际上是从带有验证的上一页设置的,因此它永远不应为null。
当我更新CALC_CLAUSE条件时:
WHERE ID = :P_KPI
我收到以下错误:
ORA-01403: no data found
如何在函数中引用此页面项?
您发布的代码无效(无法编译),您提供的解释是错误的。虽然它是一个简化版本,但我更喜欢你发布的准确信息。
你说的是SQL语句
SELECT DATE, '||CALC_CLAUSE||' KPI_VALUE
FROM DATA_VALUES ...
而CALC_CLAUSE
看起来像
WHERE ID = :P_KPI
所以整个查询看起来像
SELECT DATE, WHERE ID = :P_KPI KPI_VALUE
FROM DATA_VALUES ...
这没有意义。毕竟那是什么CALC_CLAUSE
?不应该是AVG(VALUE_1)
或类似的东西?
从:P_KPI
项目开始,其值似乎是NULL
:你在屏幕上看到它并不重要 - 它应该处于会话状态。最简单的方法是提交页面,所以 - 你做到了吗?
尝试创建一个存储函数(在数据库中,而不是在Apex中)并将其作为参数传递给P_KPI值。然后测试你得到的,以及结果。使用动态SQL时,最好将DBMS_OUTPUT.PUT_LINE
生成的语句(在您的示例中为SQL_STMT
),将其复制/粘贴到SQL * Plus(或您使用的任何其他工具,如SQL Developer)中,然后查看是否它工作正常。
例如:
CREATE OR REPLACE FUNCTION f_stmt (par_kpi IN NUMBER)
RETURN VARCHAR2
IS
sql_stmt VARCHAR2 (32767);
calc_clause VARCHAR2 (4000);
BEGIN
SELECT calculation
INTO calc_clause
FROM kpi_types
WHERE id = par_kpi;
sql_stmt :=
'SELECT DATE, '
|| calc_clause
|| ' KPI_VALUE '
|| ' FROM DATA_VALUES '
|| ' WHERE TYPE_ID = '
|| par_kpi
|| ' GROUP BY DATE';
DBMS_OUTPUT.put_line (sql_stmt);
RETURN sql_stmt;
END;
从Littlefoot建议的存储函数开始,我能够使用这个解决方案:
http://vincentdeelen.blogspot.com/2014/02/interactive-report-based-on-dynamic-sql.html
我有一个页面进程,使用动态查询字符串创建一个集合。图表区域SQL现在从集合中查询,我可以使用我的所有页面项来适当地过滤数据。