Oracle Apex 中的计算未返回预期结果

Posted

技术标签:

【中文标题】Oracle Apex 中的计算未返回预期结果【英文标题】:Computation in Oracle Apex not returning expected result 【发布时间】:2016-08-01 16:43:21 【问题描述】:

我对计算点感到困惑,例如 before_header 和 after_header 等。

我有一个计算,需要取一个页面项的值,然后作为结果返回。

计算是一个PL/SQL函数体,如下:

DECLARE
   v_response varchar2(1500);
BEGIN
  IF :P4_RENEWAL_REQUIRED = 'Yes' THEN
        v_response := 'According to Register, a license renewal WILL BE required to maintain this registration. Please choose whether you agree or disagree with this statement.';
 ELSE
       v_response:='Forget about it...';
 END IF;
  return v_response;
END;

页面项目 :P4_RENEWAL_REQUIRED 是一个计算字段,它是一个 SQL 值,它依赖于数据库填充的页面项目 P4_RENEWAL_NOT_REQUIRED。它只是将“是”变为“否”,将“否”变为“是”。

SELECT (CASE WHEN V('P4_RENEWAL_NOT_REQUIRED')='Yes' Then 'No' ELSE 
CASE WHEN  V('P4_RENEWAL_NOT_REQUIRED')='No' Then 'Yes' ELSE '??' END END) FROM DUAL

我的计算不会返回结果。 P4_RENEWAL_REQUIRED 值显然是“是”,但计算将返回“忘记它”。如果我进入页面编辑视图,然后再次运行该页面 - 值显示正确的值

'根据注册,将需要更新许可证才能维持此注册。请选择您是否同意此声明。'

这对我来说意味着计算是在 P4_RENEWAL_REQUIRED 的旧会话值上运行的。

我不确定计算点与此有什么关系,但如果我有数据通过在 After Header 上执行的 Fetch Row 进程返回,然后填充区域中的字段,例如 P4_RENEWAL_NOT_REQUIRED,然后正在计算 P4_RENEWAL_REQUIRED....如何计算以填充另一个区域中的字段,该区域依赖于现有页面项目?

我尝试让我的计算在页脚之前、区域之前、页脚之后等执行,但没有任何效果。

我不确定所有 Before Footer 是如何工作的,或者当所有这些都呈现在服务器端时,页面项目是如何填充的。

例如,如果我将计算设置为计算“区域后”,那么在区域中使用该值是否为时已晚,因为区域已经被渲染?

如果我需要在计算中计算一个值以在某个区域中使用它并使用“区域前”计算点,请在该点通过基础查询将我需要使用的页面项目绑定到页面项目,或者我是不是太早了。

任何帮助表示赞赏。

【问题讨论】:

我不太清楚:P4_RENEWAL_NOT_REQUIRED 的来源是什么?设置为“始终”还是“仅当会话状态为空时”? 设置为始终 对不起,可能没有明确说明:该项目的来源类型,设置为什么? SQL 查询? P4_RENEWAL_NOT_REQUIRED 是一个数据库列,我通过在字段 P4_RENEWAL_REQUIRED 中反转它(是->否,否->是)来转换它,这是一个 SQL 语句,我注意到它没有设置为“总是” SELECT (CASE WHEN V('P4_RENEWAL_NOT_REQUIRED')='Yes' Then 'No' ELSE CASE WHEN V('P4_RENEWAL_NOT_REQUIRED')='No' Then 'Yes' ELSE '??' END END) FROM DUAL 好吧 - 对于初学者:它至少应该设置为“始终”:您希望每次呈现页面时都“检索”该值 - 尽管存在其他问题 【参考方案1】:

“使用的来源”应设置为“始终”,因为您希望该值反映它的从属值。当设置为“仅当会话状态为空”时,仅当会话状态为空时才会获取该值。在第一次提交(或在会话状态中设置值的任何其他方法,例如计算)之后,将不再每次都检索源。这会给您一种价值已过时的印象。

至于文档:它通常非常透明,但通常存在一些混淆的地方是通过获取行过程检索值时:该过程获取相关项目(源=数据库列)的值并将它们保存在内存中渲染的持续时间(“内存中会话状态”)。这些值将始终用于项目的源,尽管这些值之后不会保留在会话状态中(=当渲染完成时)。您可以通过在页面呈现后检查会话状态来验证这一点:全部为空!我知道我在某处读过这篇文章,但文档本身并没有详细说明“获取行”的工作原理。

计算将永久设置会话状态中项目的值。是的 - 你可以使用它们来设置一个项目的价值,它有这个额外的效果。这“导致”了这里的问题(组合):只要不通过提交保留会话状态,只需在项目源中导出值就可以正常工作。由于使用了计算,因此始终忽略源,因为使用了“仅当会话状态为空时”。

虽然对数据库列执行计算确实设置了会话状态,但内存中的会话状态和源类型已否决了该值。渲染后通过计算设置的会话状态仍然存在。提交时提交的值将再次进入会话状态。所以,这是一个奇怪的情况。但这可能真的很奇怪 - 尽量避免这种情况,因为它会通过这种混乱来逻辑。

这确实为不同的计算点赋予了意义。您可以在渲染结束后计算一个项目,并设置会话状态。该项目将在计算之前使用一个值渲染(如果在渲染之后完成,否则,它取决于例如源),然后将该值保留在会话状态中。 我无法举出一个例子,因为我从来没有使用过那种情况。就个人而言,之前和之后的区域点对我来说意义不大。 前标头和后标头通常是最常用的点,并且与所有处理一样,将是顺序的。在适当的地方使用。

再一次,在所有项目都通过其源设置派生的正常情况下:它们将表现正常并且不会发生会话状态的持久性。进程(“Fetch”除外!)和计算将使值在会话状态中持续存在。

【讨论】:

以上是关于Oracle Apex 中的计算未返回预期结果的主要内容,如果未能解决你的问题,请参考以下文章

Oracle Apex 的对象浏览器中未显示任何数据

Oracle APEX 交互式报告中的错误 - ORA-01427:单行子查询返回多于一行

Oracle APEX 中的条件值列表?

Oracle Apex Apex_application.G_fNN 处理未提取所有值

列表中的元素计数未产生预期结果

在交互式网格 Oracle Apex 中的自定义验证中突出显示列