我遇到了将页面项的值绑定到匿名PL / SQL块进程中的声明变量的问题。
问题是页面项(:P4550_REQUESTOR)在满足条件之前没有填充值。看起来PL / SQL块进程在加载页面后立即将变量绑定到空值,尽管在单击特定按钮之前该过程不会触发。
这是我的代码:
DECLARE
v_email_to app_user.email%type;
v_requestor VARCHAR2(15);
BEGIN
v_requestor := :P4550_REQUESTOR;
BEGIN
SELECT email INTO v_email_to
FROM app_user
WHERE userid = v_requestor;
END;
SEND_APEX_MAIL (
v_email_to,
'Your vacancy request has been rejected.'
|| chr(10)
|| 'Emailed to: ' || v_email_to
|| chr(10)
|| 'Requestor: ' || v_requestor,
'Vacancy Request Rejected'
);
END;
有没有人对此有任何想法?
如果我将值硬编码到v_requestor,那么块工作正常。如果我在页面加载后尝试获取P4550_REQUESTOR的值,则为空。单击编辑按钮后,将填充P4550_REQUESTOR。
** **更详细** **
P4550_REQUESTOR是位于空缺请求区域内的页面项目,仅在满足条件时显示。具体而言,条件是与在页面加载时创建的表行相关联的编辑按钮。单击编辑按钮将显示详细信息区域,以及要填充的关联页面项。
空缺请求区域中的页面项值通过自动行提取填充,该提取在标题之后触发。
P4550_REQUESTOR的源类型为DB列。
触发上述代码的过程设置为触发提交 - 计算和验证后
如果我在页面加载时记录P4550_REQUESTOR的值,则显示为null。如果我在单击编辑按钮后记录该值,则会得到预期的字符串值。
答案 0 :(得分:3)
(这在其他编程学科和环境中考虑实际上很有用。)
问题是页面项(:P4550_REQUESTOR)在满足条件之前没有填充值。看起来PL / SQL块进程在加载页面后立即将变量绑定到空值,尽管在单击特定按钮之前该过程不会触发。
问题陈述重写了Apex术语,并以实际问题的形式呈现:
- 页面上有一个
REPORT REGION
,其中包含对数据表/视图的直接引用的结果。此报告由名为" Automated Fetch"的Apex流程管理。并通过加载页眉自动启动。- 页面上有
FORM ITEM
,有条件地由用户进行的BUTTON ITEM
选择填充。BUTTON ITEM
是报告结果的一部分。- 有多个按钮项。每个都与每个报告记录的值相关联。
- 如果用户未选择
醇>BUTTON ITEM
中的REPORT REGION
,则FORM ITEM
仍然未分配且包含" null"值。
有一个已定义的PL / SQL代码块,设置为在按下SUBMIT BUTTON
项目时执行(也在同一页面上)。为什么我的代码块(已定义的页面处理)在没有先从BUTTON ITEM
首先按下REPORT REGION
的情况下被触发时使用空值运行?
如果你在程序语言的范式下思考,答案就不明显了。如果没有深入研究这个主题的演讲,我可以通过这种方式对OP的问题空间进行视觉布局,以说明如何使问题更加明显:
这是我实现的Apex页面设计。它的通用性足以用作其他Apex设计的模板。此图中没有流向箭头,因为它是一个有状态系统。有一件事会导致另一件事情发生,等等......但并非总是而且并非所有事情都在同一时间。
尝试浏览一些用例,了解图中分解的元素如何一起运行。每个用户可以采用任意数量的点击组合和互动,但有一个共性:
使用案例#1
{MyPage:SQLReport:ThisButton}
{MyPage:SQLReport}
{MyPage:SQLReport:ThisButton} #3
,报告记录与按钮项目之间关联的值将传递到:{MyPage:HTML-Region:ThisItem}
{MyPage:HTML-Region:ThisSubmit}
按钮通知系统继续。{MyPage:RunCodeBlock}
使用案例#2
{MyPage:SQLReport}
区域中显示的结果。{MyPage:HTML-Region:ThisSubmit}
按钮通知系统继续。{MyPage:HTML-Region:ThisItem}
的状态此时尚未从初始空值更改...选择了提交按钮后){MyPage:RunCodeBlock}
使用案例#3
{MyPage:SQLReport:ThisButton}
{MyPage:SQLReport}
{MyPage:SQLReport:ThisButton} #3
,报告记录与按钮项目之间关联的值将传递到:{MyPage:HTML-Region:ThisItem}
{MyPage:SQLReport:ThisButton}
中的一条记录中选择不同选项中的{MyPage:SQLReport}
。{MyPage:SQLReport:ThisButton} #3
,报告记录与按钮项目之间关联的值将传递到:{MyPage:HTML-Region:ThisItem}
{MyPage:HTML-Region:ThisSubmit}
按钮通知系统继续。{MyPage:RunCodeBlock}
每个案例之间的差异应说明为什么依赖值(ThisItem
,或更具体地说,页面项P4550_REQUESTOR
)在一个用例中与另一个用例相比为空。
我使用的表名为STAR_EMPS。它类似于EMP表,但只有三列:ename,deptno和salary。虽然它不是非常重要,但这是我用来填充STAR_EMPS的数据集:
我使用了一个名为STAR_EMPS_LOG的简单双列表来捕获成功执行的过程调用的输出。您可以只使用一列完成相同的操作,但我想要一个用于跟踪每个事件记录顺序的顺序ID - 用于运行多个测试用例。该过程是此页面上保留的几个已定义过程之一:
包含在:{MyPage:RunCodeBlock}如下:
DECLARE
-- output from this procedure will be recorded in the star_emps_log
-- table. {MyPage:RunCodeBlock}
mycelebrity star_emps.ename%TYPE:= :P17_CELEBRITY_NAME;
mylogmessage star_emps_log.log_message%TYPE;
BEGIN
-- Conditional; changes message based on the value set for the
-- page item.
if mycelebrity is null then
mylogmessage:= 'No button was pressed on the previous page.';
else
mylogmessage:= 'The user selected: ' || mycelebrity ||
' from the report list.';
end if;
-- populate value from the page item.
INSERT INTO star_emps_log (log_message)
VALUES (mylogmessage);
commit;
END;
这是页面布局的设置方式:
TWO Page进程:PROCESS和BRANCH需要使用引用BUTTON触发项的相同设置进行链接。
运行三个建议的方案开始。验证系统是否正确解释请求。这就是页面布局的样子:
系统上的两个流程有一个定义,以前的讨论中没有提到可以解决我们手头的原始问题:
一旦被打破,这是一件好事,事实证明这是一个微不足道的案例。这里描述的图表方法应该扩展到不同复杂度的其他Apex应用程序。脱离代码,锁定术语并试图在没有实际代码的情况下描述系统和流程,具有相当大的实用性。如果这种方法有助于您自己的Oracle Apex设计挑战,请务必分享任何故事。
冠!
答案 1 :(得分:0)
原始的,冗长的答案似乎使问题过于复杂。 session state concepts manual更简洁地涵盖了这种行为。
P4550_REQUESTOR应该是从向导创建的正常项目,使用:P4550_REQUESTOR将在提交后运行的进程中返回一个值,因为提交进程会将浏览器中的值移动到会话状态。
如果P4550_REQUESTOR有条件地呈现,那么它将始终为null并且我不确定如果你试图设置它会发生什么 - 可能取决于如何。
在类似的说明中,如果您使用了& P4550_REQUESTOR。要对进程进行参数化,您将面临最初描述的行为(并使代码不太安全)