我正在将旧的 Perl/MySQL 数据库应用程序转换为 Oracle APEX,旧系统中有一个功能我一直无法找到实现方法...
假设每个表格由列表屏幕(交互式网格)、仅查看屏幕(所有字段设置为只读的表单)和输入/编辑屏幕(第二个表单)组成;并且有一个 ID(主键)、名称和注释(文本区域)字段,尽管它们显然还有许多其他字段。 为此,假设我们有名为 table_1、table_2 和 table_3 且具有顺序 ID 的表,然后名称分别具有值 name_1、name_2 和 name_3。
当前系统使用所谓的“自由格式链接”,以便在输入屏幕上输入的表:名称将显示指向与名称匹配的实际记录或记录的链接。
示例:
如果他们在 table_1 输入表单的 Comments 字段中输入
有什么方法可以在 APEX 中做到这一点吗? 任何建议将不胜感激。
我尝试更改 URL 以使用名称字段而不是 ID(主键),但失败了。 我没有找到编写过滤器脚本的方法或任何其他方法来执行此操作。
这可以使用源类型为“返回 SQL 查询的 PL/SQL 函数体”的报告来实现。 emp/dept 样本表的示例。用户可以输入 ENAME:KING 以获取 KING 表单的链接,或输入 DEPT:ACCOUNTING 以获取 ACCOUNTING 表单的链接。示例位于第 142 页,表单的链接不传递主键参数,但这应该是微不足道的。
创建文本字段 P142_SEARCH_TERM 类型的页面项目
创建“返回 SQL 查询的 PL/SQL 函数体”类型的经典报告。使用以下来源:
DECLARE
l_query varchar2(4000);
l_table_name varchar2(400);
l_key varchar2(400);
l_search_term_t apex_t_varchar2 := apex_t_varchar2();
--ORA-06533: Subscript beyond count
subscript_beyond_count EXCEPTION;
PRAGMA EXCEPTION_INIT (subscript_beyond_count, -06533);
invalid_search_args EXCEPTION;
BEGIN
BEGIN
l_search_term_t := apex_string.split(NVL(:P142_SEARCH_TERM,'EMP:KING'),':');
l_table_name := l_search_term_t(1);
l_key := l_search_term_t(2);
EXCEPTION WHEN subscript_beyond_count THEN
RAISE invalid_search_args;
END;
IF l_table_name = 'EMP' THEN
l_query :=
q'!select
ename,
apex_page.get_url(
p_page => 142
)
from
emp
where
ename = '%0'!';
ELSIF l_table_name = 'DEPT' THEN
l_query :=
q'!select
dname,
apex_page.get_url(
p_page => 141
)
from
dept
where
dname = '%0'!';
ELSE
RAISE invalid_search_args;
END IF;
l_query := apex_string.format(l_query, l_key);
apex_debug.info(p_message =>'SO Debug: '||l_query);
return(l_query);
EXCEPTION WHEN invalid_search_args THEN
l_query :=
q'!select
'Invalid search argument: "'||:P142_SEARCH_TERM||'"'
from
dual!';
return(l_query);
END;
设置要提交的页面项目、通用列名称和通用列计数(这是必需的,因为否则 APEX 将从 INIT 子句中添加 order by 子句)
针对 P142_SEARCH_TERM 的更改创建动态操作以刷新经典报告区域。
要解析文本并用其他页面的链接替换占位符,可以执行以下操作。
示例:文本可以包含指向 EMP 和 DEPT 页面的链接,引用员工姓名和部门名称。
名称:P276_PLACEHOLDER_TEXT
类型:文本区域
注意:这也可以通过动态操作和区域刷新来完成。在这种情况下,请使用该地区的“要提交的项目”属性。
来源:
declare
l_result clob DEFAULT EMPTY_CLOB();
l_regex VARCHAR2(30) := '(\<[a-z0-9:]+\>)';
l_search_term_t apex_t_varchar2 := apex_t_varchar2();
l_page VARCHAR2(100);
l_item_name VARCHAR2(100);
l_key VARCHAR2(100);
l_parsed_placeholder VARCHAR2(4000);
l_link VARCHAR2(4000);
begin
l_result := :P276_PLACEHOLDER_TEXT;
FOR r_placeholders IN
(
WITH t(valt) AS
(SELECT :P276_PLACEHOLDER_TEXT as valt FROM dual)
SELECT
translate(regexp_substr(valt,l_regex,1,level,'i'),'*<>','_') as c
FROM t
CONNECT BY translate(regexp_substr(valt,l_regex,1,level,'i'),'<>','_') IS NOT NULL
)
LOOP
BEGIN
l_search_term_t := apex_string.split(r_placeholders.c,':');
l_page := CASE l_search_term_t(1)
WHEN 'EMP' THEN 277
WHEN 'DEPT' THEN 278
ELSE NULL END;
l_item_name := CASE l_search_term_t(1)
WHEN 'EMP' THEN 'P277_ENAME'
WHEN 'DEPT' THEN 'P278_DNAME'
ELSE NULL END;
l_parsed_placeholder := apex_page.get_url (p_page => l_page, p_items => l_item_name, p_values => l_search_term_t(2));
END;
l_link := apex_string.format('<a href="%0">%1</a>',l_parsed_placeholder,r_placeholders.c);
l_result := REPLACE(l_result,'<'||r_placeholders.c||'>',l_link);
END LOOP;
return l_result;
end;
此代码非常原始,需要添加大量错误处理才能正常工作(例如,占位符中不存在的页面时的错误处理、占位符不完整时的错误处理等),但这应该可以帮助您继续。