【问题标题】:Oracle Forms: only iterate through selected recordsOracle Forms:仅遍历选定的记录
【发布时间】:2014-12-12 15:45:51
【问题描述】:

我的问题如下:

我有一个基于 FROM_clause 的数据块,从两个表中查询相关数据。在同一个数据块中,我有一个复选框来选择行,作为非数据库项。当用户按下按钮时,它会将这些记录中的某些信息插入到表中。

目前我正在遍历所有记录,检查该行的复选框是否已激活,具体取决于执行插入操作。如果数据块只显示几行,或者用户只是在列表顶部选择了一些行,这一切都很好。 (我的循环从 FIRST_RECORD 迭代到 LAST_RECORD,或者直到插入操作的数量等于所选行的数量)。

但在大多数情况下,数据块会显示几千条记录。如果用户现在选择列表末尾的一些行(如记录#8000),我的循环将(无用地)遍历数千条记录以仅插入几行。这需要很多时间,而且是不必要的。

我正在使用 Oracle Form Builder 11g

我怎样才能创建一个循环,它只会遍历选定的记录? 任何提示或代码示例将不胜感激!

【问题讨论】:

    标签: database plsql oracleforms


    【解决方案1】:

    为了帮助可能面临类似问题的其他人,我想发布我的解决方案。 我松散地将我的实现基于我在研究期间发现的this tutorial

    我在 WHEN_NEW_FORM_INSTANCE 触发器中创建了一个 RecordGroup 并添加了我需要存储的所有列:

    declare
      rg_name varchar2(40) := 'SELECTED';
      rg_id   recordgroup;
      gc_id   groupcolumn;
    
    begin
      /* Make sure the record group does not already exist.  */
      rg_id := find_group(rg_name);
      /* If it does not exist, create it and add the  
      ** necessary columns to it.  */
      if id_null(rg_id) then
        rg_id := create_group(rg_name);
        /* Add columns to the record group */
        gc_id := add_group_column(rg_id, 'Barcode', number_column);
        gc_id := add_group_column(..);
    
      end if;
    

    然后我更改了我的 WHEN_CHECKBOX_CHANGED 以根据复选框的值在 RecordGroup 中添加或删除行。

    declare
      row_no     number;
      rg_id      recordgroup := find_group('SELECTED');
      gc_id      groupcolumn;
      total_rows number;
      barcode    number;
    
    begin
      total_rows := get_group_row_count(rg_id);
      if :block.checkbox = 1 then
        /* Add selected row to the RecordGroup */
        add_group_row(rg_id, end_of_group);
        set_group_number_cell('SELECTED.BARCODE',
                              total_rows + 1,
                              :block.number_item);
      else
         /* Find selected row in RecordGroup and remove it */
         for i in 1 .. total_rows loop
           barcode := get_group_number_cell('SELECTED.BARCODE', i);
           if :block.number_item = barcode then
             row_no := i;
             exit;
           end if;
         end loop;
    
        delete_group_row('SELECTED', row_no);
      end if;
    end;
    

    在我的 WHEN_BUTTON_PRESSED 触发器中,它仅循环通过存储在 RecordGroup 中的选定行

    declare
      selected number;
      row_no   number;
    begin
      ..
      selected := get_group_row_count('SELECTED');
      for j in 1 .. selected loop
        begin
          barcode := get_group_number_cell('SELECTED.BARCODE', j);
          ..
          insert into (..);
          commit;
        exception
          when others then
            error_logging(..);
        end;
      end if;
      delete_group_row('SELECTED', all_rows);
      ..
    end;
    

    【讨论】:

      【解决方案2】:

      一般来说,如果一个块可能包含超过几十条记录,我会尽可能避免循环遍历这些记录。过去,我通过两种方式解决了这个问题 - 选择适合您的方式。

      1. 将复选框值存储在 GTT 中,然后查询 GTT

        创建一个全局临时表,并将复选框基于该 GTT。当用户单击按钮时,让按钮触发 POST 值到表;然后,您可以对 GTT 执行 SQL 查询以查找所选值。

      2. 将选定的行存储在数组中,然后循环遍历数组

        向复选框添加触发器,以便无论何时选中或取消选中,都会在 PL/SQL 数组中添加或删除具有相关记录号的记录。然后,您可以循环遍历这个数组,这比浏览记录块要快得多。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-02-04
        • 2016-07-18
        • 1970-01-01
        • 2020-01-13
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多