ORACLE apex - 使用 PL/SQL 遍历复选框项目
ORACLE apex - looping through checkbox items using PL/SQL
我的页面 P3_Checkbox1
上有一个从数据库中填充的复选框。如何在 PL/SQL 代码中遍历复选框的所有选中值?
我假设 APEX_APPLICATION.G_F01
仅由 sql 生成的复选框使用,我不能将它用于常规复选框,因为它不会填充 G_Fxx 数组。
我想我现在明白你在说什么了。
例如,假设 P3_CHECKBOX1
复选框项允许 3 个值 (display/return):
- 缺席:-1
- 未知:0
- 此处:1
我创建了一个按钮(仅 SUBMIT
页面)和两个将显示选中值的文本项:P3_CHECKED_VALUES
和 P3_CHECKED_VALUES_2
。
然后我创建了一个 process,它在按下按钮时触发。该过程如下所示(请同时阅读评论):
begin
-- This is trivial; checked (selected) values are separated by a colon sign,
-- just like in a Shuttle item
:P3_CHECKED_VALUES := :P3_CHECKBOX1;
-- This is what you might be looking for; it uses the APEX_STRING.SPLIT function
-- which splits selected values (the result is ROWS, not a column), and these
-- values can then be used in a join or anywhere else, as if it was result of a
-- subquery. The TABLE function is used as well.
-- LISTAGG is used just to return a single value so that I wouldn't have to worry
-- about TOO-MANY-ROWS error.
with
description (code, descr) as
(select -1, 'Absent' from dual union all
select 0 , 'Unknown' from dual union all
select 1 , 'Here' from dual),
desc_join as
(select d.descr
from description d join (select * from table(apex_string.split(:P3_CHECKED_VALUES, ':'))) s
on d.code = s.column_value
)
select listagg(j.descr, ' / ') within group (order by null)
into :P3_CHECKED_VALUES_2
from desc_join j;
end;
假设已经检查了 Absent 和 Unknown 值。 PL/SQL 过程的结果是:
P3_CHECKED_VALUES = -1:0
P3_CHECKED_VALUES_2 = Absent / Unknown
你可以随意改写;这只是一个例子。
关键字:
APEX_STRING.SPLIT
TABLE
函数
希望对您有所帮助。
[编辑:循环选择的值]
遍历这些值并不困难;您可以按如下方式进行(请参阅游标 FOR
循环):
declare
l_dummy number;
begin
for cur_r in (select * From table(apex_string.split(:P3_CHECKED_VALUES, ':')))
loop
select max(1)
into l_dummy
from some_table where some_column = cur_r.column_value;
if l_dummy is null then
-- checked value does not exist
insert into some_table (some_column, ...) valued (cur_r.column_value, ...);
else
-- checked value exists
delete from some_table where ...
end if;
end loop;
end;
但是,我不确定您所说的 "particular combination is in the database" 是什么意思。这是否意味着您将以冒号分隔的值存储到 table 中的列中?如果是这样,上面的代码也不会工作,因为你会比较,例如
-1
到 0:-1
然后
0
到 0:-1
这不是真的(除了最简单的情况,当检查和存储的值只有一个值时)。
尽管 Apex 的 "multiple choices" 看起来不错,但当您实际上 做 某些事情时,它们可能会变成噩梦(就像您的情况一样)。
也许你应该先排序复选框值,对数据库值排序,然后比较这两个字符串。
表示LISTAGG
可能会再次派上用场,比如
listagg(j.descr, ' / ') within group (order by j.descr)
数据库值可以这样排序:
SQL> with test (col) as
2 (select '1:0' from dual union all
3 select '1:-1:0' from dual
4 ),
5 inter as
6 (select col,
7 regexp_substr(col, '[^:]+', 1, column_value) token
8 from test,
9 table(cast(multiset(select level from dual
10 connect by level <= regexp_count(col, ':') + 1
11 ) as sys.odcinumberlist))
12 )
13 select
14 col source_value,
15 listagg(token, ':') within group (order by token) sorted_value
16 from inter
17 group by col;
SOURCE SORTED_VALUE
------ --------------------
1:-1:0 -1:0:1
1:0 0:1
SQL>
将它们都排序后,您可以将它们进行比较,然后将它们 INSERT
或 DELETE
排成一行。
我的页面 P3_Checkbox1
上有一个从数据库中填充的复选框。如何在 PL/SQL 代码中遍历复选框的所有选中值?
我假设 APEX_APPLICATION.G_F01
仅由 sql 生成的复选框使用,我不能将它用于常规复选框,因为它不会填充 G_Fxx 数组。
我想我现在明白你在说什么了。
例如,假设 P3_CHECKBOX1
复选框项允许 3 个值 (display/return):
- 缺席:-1
- 未知:0
- 此处:1
我创建了一个按钮(仅 SUBMIT
页面)和两个将显示选中值的文本项:P3_CHECKED_VALUES
和 P3_CHECKED_VALUES_2
。
然后我创建了一个 process,它在按下按钮时触发。该过程如下所示(请同时阅读评论):
begin
-- This is trivial; checked (selected) values are separated by a colon sign,
-- just like in a Shuttle item
:P3_CHECKED_VALUES := :P3_CHECKBOX1;
-- This is what you might be looking for; it uses the APEX_STRING.SPLIT function
-- which splits selected values (the result is ROWS, not a column), and these
-- values can then be used in a join or anywhere else, as if it was result of a
-- subquery. The TABLE function is used as well.
-- LISTAGG is used just to return a single value so that I wouldn't have to worry
-- about TOO-MANY-ROWS error.
with
description (code, descr) as
(select -1, 'Absent' from dual union all
select 0 , 'Unknown' from dual union all
select 1 , 'Here' from dual),
desc_join as
(select d.descr
from description d join (select * from table(apex_string.split(:P3_CHECKED_VALUES, ':'))) s
on d.code = s.column_value
)
select listagg(j.descr, ' / ') within group (order by null)
into :P3_CHECKED_VALUES_2
from desc_join j;
end;
假设已经检查了 Absent 和 Unknown 值。 PL/SQL 过程的结果是:
P3_CHECKED_VALUES = -1:0
P3_CHECKED_VALUES_2 = Absent / Unknown
你可以随意改写;这只是一个例子。
关键字:
APEX_STRING.SPLIT
TABLE
函数
希望对您有所帮助。
[编辑:循环选择的值]
遍历这些值并不困难;您可以按如下方式进行(请参阅游标 FOR
循环):
declare
l_dummy number;
begin
for cur_r in (select * From table(apex_string.split(:P3_CHECKED_VALUES, ':')))
loop
select max(1)
into l_dummy
from some_table where some_column = cur_r.column_value;
if l_dummy is null then
-- checked value does not exist
insert into some_table (some_column, ...) valued (cur_r.column_value, ...);
else
-- checked value exists
delete from some_table where ...
end if;
end loop;
end;
但是,我不确定您所说的 "particular combination is in the database" 是什么意思。这是否意味着您将以冒号分隔的值存储到 table 中的列中?如果是这样,上面的代码也不会工作,因为你会比较,例如
-1
到0:-1
然后0
到0:-1
这不是真的(除了最简单的情况,当检查和存储的值只有一个值时)。
尽管 Apex 的 "multiple choices" 看起来不错,但当您实际上 做 某些事情时,它们可能会变成噩梦(就像您的情况一样)。
也许你应该先排序复选框值,对数据库值排序,然后比较这两个字符串。
表示LISTAGG
可能会再次派上用场,比如
listagg(j.descr, ' / ') within group (order by j.descr)
数据库值可以这样排序:
SQL> with test (col) as
2 (select '1:0' from dual union all
3 select '1:-1:0' from dual
4 ),
5 inter as
6 (select col,
7 regexp_substr(col, '[^:]+', 1, column_value) token
8 from test,
9 table(cast(multiset(select level from dual
10 connect by level <= regexp_count(col, ':') + 1
11 ) as sys.odcinumberlist))
12 )
13 select
14 col source_value,
15 listagg(token, ':') within group (order by token) sorted_value
16 from inter
17 group by col;
SOURCE SORTED_VALUE
------ --------------------
1:-1:0 -1:0:1
1:0 0:1
SQL>
将它们都排序后,您可以将它们进行比较,然后将它们 INSERT
或 DELETE
排成一行。