Oracle Forms:仅迭代选定的记录

时间:2014-10-17 05:44:42

标签: database plsql oracleforms

我的问题如下:

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

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

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

我正在使用Oracle Form Builder 11g

如何创建循环,只会迭代所选的记录? 任何提示或代码示例都将不胜感激!

2 个答案:

答案 0 :(得分: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;

答案 1 :(得分:0)

通常,如果一个块可能包含多于几十个记录,我将尽可能避免在记录上循环。在过去,我已经用两种方式解决了这个问题 - 选择哪一种适合你。

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

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

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

    向复选框添加触发器,以便在选中或取消选中时,会在PL / SQL阵列中添加或删除具有相关记录编号的记录。然后,您可以遍历此数组,这将比浏览记录块快得多。