我的问题如下:
我有一个基于FROM_clause的数据块,查询两个表中的相关数据。在同一个数据块中,我有一个复选框来选择行,作为非数据库项。当用户按下按钮时,它会将这些记录中的某些信息插入表格中。
目前我正在遍历所有记录,检查此行的复选框是否已激活,具体取决于执行插入操作。如果数据块仅显示几行,或者用户刚刚在列表顶部选择了一些行,则一切正常。 (我的循环从FIRST_RECORD迭代到LAST_RECORD,或直到插入操作的数量等于所选行的数量)。
但是在大多数情况下,数据块将显示几千条记录。如果用户现在选择列表末尾的某些行(如记录#8000),我的循环将(无用地)遍历数千条记录以插入几行。这需要很多时间,而且是不必要的。
我正在使用Oracle Form Builder 11g
如何创建循环,只会迭代所选的记录? 任何提示或代码示例都将不胜感激!
答案 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)
通常,如果一个块可能包含多于几十个记录,我将尽可能避免在记录上循环。在过去,我已经用两种方式解决了这个问题 - 选择哪一种适合你。
将复选框值存储在GTT中,然后查询GTT
创建一个全局临时表,并以该GTT上的复选框为基础。当用户单击该按钮时,让按钮触发POST值到表中;然后,您可以对GTT执行SQL查询以查找所选值。
将所选行存储在数组中,然后循环遍历数组
向复选框添加触发器,以便在选中或取消选中时,会在PL / SQL阵列中添加或删除具有相关记录编号的记录。然后,您可以遍历此数组,这将比浏览记录块快得多。