ORACLE apex - 使用 PL/SQL 循环通过复选框项目

Posted

技术标签:

【中文标题】ORACLE apex - 使用 PL/SQL 循环通过复选框项目【英文标题】:ORACLE apex - looping through checkbox items using PL/SQL 【发布时间】:2018-10-18 15:25:07 【问题描述】:

我的页面P3_Checkbox1 上有一个从数据库填充的复选框。如何在 PL/SQL 代码中遍历我的复选框的所有选中值?

我假设APEX_APPLICATION.G_F01 仅由 sql 生成的复选框使用,我不能将它用于常规复选框,因为它不会填充 G_Fxx 数组。

【问题讨论】:

这是一个什么样的地区? 只是一个带有选择列表和复选框的静态区域 所以 - 页面上只有一个复选框项 (P3_CHECKBOX1)?如果是这样,我不太明白你会循环什么。你知道 - 循环意味着“多次做某事”(虽然你只能循环一次,但这没有多大意义)。我只是不明白这个问题...如果可能,请发布该页面的屏幕截图,以便我们可以看到您拥有的内容。 只有一个复选框项,但它有多个值 - 有点像复选框列表 所以如果我从我的 PL/SQL 中获取 P3_Checkbox1 页面项,我将得到一个数组,我需要循环遍历它 【参考方案1】:

我想我现在明白你在说什么了。

例如,假设P3_CHECKBOX1复选框项允许3个值(显示/返回):

缺席:-1 未知:0 这里:1

我创建了一个按钮(这将只是 SUBMIT 页面)和两个将显示选中值的文本项:P3_CHECKED_VALUESP3_CHECKED_VALUES_2

然后我创建了一个在按下按钮时触发的进程。该过程如下所示(请同时阅读 cmets):

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;

但是,我不确定您所说的“特定组合在数据库中”是什么意思。这是否意味着您要将冒号分隔的值存储到该表的列中?如果是这样,上面的代码也不会工作,因为你会比较,例如

-10:-1 然后 00:-1

这不是真的(除了在最简单的情况下,检查和存储的值只有一个值)。

虽然 Apex 的“多项选择”看起来不错,但当您必须对它们进行实际某些事情时(例如您的情况),它们可能会成为一场噩梦。

也许你应该先排序复选框值,排序数据库值,然后比较这两个字符串。

这意味着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>

将它们都排序后,您可以对它们进行比较,并在INSERTDELETE 一行中进行比较。

【讨论】:

这不是我想要的。我需要一些方法来遍历这些逗号分隔的值。我计划在循环中做的是检查特定组合是否已经在数据库中,如果不是,我想插入它。如果数据库中有未经检查的组合 - 删除它 我已经编辑了我的消息并添加了更多信息。请看一下。 谢谢!我的意思是我有一个存储两个整数值的数据库表——一个来自选择列表,另一个来自复选框。例如,如果选择列表的选定值为 101,复选框值为 1、2、3、4,那么我需要检查该数据库表中的组合 101 和 1、101 和 2 等... 不客气。好的,我想您将能够使用我发布的光标 FOR 循环作为消息编辑部分的第一个代码。祝你好运! 谢谢!你总是很乐于助人

以上是关于ORACLE apex - 使用 PL/SQL 循环通过复选框项目的主要内容,如果未能解决你的问题,请参考以下文章

运行时解析 PL/SQL 的 Oracle Apex Cards 视图

Oracle Apex:PL/SQL 块中的 Javascript 代码

Oracle APEX PL/SQL 错误

将PL / SQL块与交互式网格一起使用(Oracle Apex)

ORACLE APEX PL SQL 过程错误

在 oracle apex 中将 sql 查询重写为 pl/sql