首页 > 数据库 > Oracle > 自动行号功能实现不同方法研究
只需要将“序号”定义成公式,并将公式设置为:get_block_property('block_name',current_record)就可以实现了,或者把这行语句放到“When-Create-Record”触发器中。
缺点:增改删时,行号不能自动刷新。
在block的三个触发器中添加相应的代码:
缺点:对于记录数很少的table适用,当table中的记录很多时,由于使用了循环操作,所以会影响效率。
为了防止按F11时也生成序号,影响查询,可以在生成前加入以下条件:
IF (:SYSTEM.MODE != ‘ENTER-QUERY’) THEN
Step1创建3个参数和一个非数据库字段
Parametername type InitialValue
P_BOLCKNAME_MAX_LINE_NUMBER number
P_BOLCKNAME_VALIDATE_FLAG char
P_BOLCKNAME_RESET_LINE_NUMBER char N
在使用line_number功能的Block中添加一个非数据库Item
Columnname type InitialValue
VAL_REC_FIRED_FLAG char N
Step2在block-leveltrigger中添加以下代码
(1) pre_query
BOLCKNAME.line_num('PRE-QUERY');
(2) post_query
BOLCKNAME.line_num('POST-QUERY');
(3) when_create_record
IF :PARAMETER. P_BOLCKNAME_RESET_LINE_NUMBER = 'Y' THEN
copy('1',:PARAMETER.P_BOLCKNAME_MAX_LINE_NUMBER);
:PARAMETER.P_BOLCKNAME_RESET_LINE_NUMBER:= 'N';
END IF;
BOLCKNAME.line_num('INIT');
(4) when-validate-record
BOLCKNAME.line_num('WHEN-VALIDATE-RECORD');
(5) when-new-record-instance
BOLCKNAME.line_num('WHEN-NEW-RECORD-INSTANCE');
(6) on-clear-details(子块需添加,主块不需该trigger)
IF :system.cursor_block = 'BOLCKNAME' andnvl(:system.coordination_operation,'X') in('CREATE_RECORD','NEXT_RECORD')
THEN
copy('Y',P_BOLCKNAME_RESET_LINE_NUMBER);
END IF;
(7) pre_insert
BOLCKNAME.catalog_group_line_unique; --行号唯一性的检查
(8) pre_update
BOLCKNAME.catalog_group_line_unique; --行号唯一性的检查
在VAL_REC_FIRED_FLAG的Item leveltrigger中添加以下代码
(1) WHEN-VALIDATE-ITEM
BOLCKNAME.catalog_group_line_unique; --行号唯一性的检查
BOLCKNAME.line_num('WHEN-VALIDATE-ITEM');
Step3在ProgrameUnit中添加名为BOLCKNAME的PACKAGE
在PACKAGE BLOCKNAME BODY中添加
PROCEDURE line_num(event VARCHAR2) IS
x_max_line_num NUMBER:= 0;
x_lines_curr_maxNUMBER;
BEGIN
IF(event = 'WHEN-VALIDATE-ITEM') THEN
--code略
END IF ;
END ;
PROCEDURE catalog_group_header_uniqueis
l_rec_num number;
BEGIN
selectcount(1) into l_rec_num
--code略
END;
具体代码参看附件:blockname_body.txt
Step4在数据库中创建下面的PACKAGE
红蓝两部分代码功能类似,区别在于蓝色代码多了一个line_type传入参数,可根据条件灵活调用。
create or replace package bodyTVSN_CONTROL_F_PKG is
PROCEDUREcheck_catalog_unique(p_catalog_header_idINNUMBER,
P_catalog_LINE_ID INNUMBER,
P_catalog_LINE_NUM INNUMBER,
p_validate_flag OUTVARCHAR2) IS
p_record_numbernumber := 0;
BEGIN
END;
PROCEDUREget_catalog_max_num (P_catalog_header_idINNUMBER,
P_MAX_NUM OUTNUMBER) IS
BEGIN
END;
PROCEDUREcheck_catalog_group_unique(p_catalog_group_header_idINNUMBER,
p_catalog_line_type INNUMBER,
P_catalog_group_LINE_ID INNUMBER,
P_catalog_group_LINE_NUM INNUMBER,
p_validate_flag OUTVARCHAR2) IS
p_record_number number :=0;
BEGIN
END;
PROCEDUREget_catalog_group_max_num(P_catalog_group_header_idINNUMBER,
p_line_type INNUMBER,
P_MAX_NUM OUTNUMBER) IS
BEGIN
END;
endTVSN_CONTROL_F_PKg;
注:此种方法有个缺陷,即可能产生断号的Line_Number,如现有行号为4,5,6的记录删除了行号为5的记录,那么新增一条记录的行号就为7,行号5就永远不可能被用到了。
顺带介绍两个和行记录有关的API:
(1) APP_RECORD.DELETE_ROW
procedureAPP_RECORD.DELETE_ROW(
check_delete BOOLEAN default FALSE, --是否检查Block的delete_allowed属性
product_name varchar2 default NULL,
message_name varchar2 default NULL);
functionAPP_RECORD.DELETE_ROW(
check_delete BOOLEAN default FALSE,
product_name varchar2 default NULL,
message_name varchar2 default NULL)
return BOOLEAN;
此API可应用删除记录时需提示时,确认后执行删除,取消则不删除,可以通过重写Block的KEY-DELREC Trigger添加APP_RECORD.DELETE_ROW;实现该功能。也可以利用下面的代码实现更复杂的删除逻辑。
IF APP_RECORD.DELETE_ROW THEN
Code1;
ELSE
Code2;
END IF;
(2) APP_RECORD. FOR_ALL_RECORDS
此API补充了本章开头介绍的Line_Number功能的断号缺陷,将两者结合起来应该是一种比较完善的解决方案,实现步骤如下:
Step 1创建itemhandler procedures
PACKAGE BODY lines IS
line_number_seq number := 0;
PROCEDURE delete_row IS
BEGIN
line_number_seq := 0;
APP_RECORD.FOR_ALL_RECORDS(’reseq_line_number’);
END delete_row;
END lines;
Step 2创建用户定义triggerRESEQ_LINE_NUMBER
lines.line_number_seq := lines.line_number_seq + 1;
:lines.line_number := lines.line_number_seq;
Step 3在KEY–DELETETrigger调用item handler procedures
lines.line_number(’KEY–DELETE’); --删除记录时调用delete_row代码重置行号
注意:当块中包含的记录数非常多时,那么重置行号将非常缓慢。如果块查询出的记录集只是所有记录的一部分,而行号又是主键字段,那么重置行号有可能导致主键重复的错误。如果在查询玩数据或保存提交后需要重置行号,那么可能需要修改record的状态将其标记为未修改。
在某些情况下,在新增、删除记录后,要求为 BLOCK中显示的 RECORD进行排序并
且编号。完成这一动作可通过以下函数来完成:
l APP_RECORD.FOR_ALL_RECORDS
例子如下:
块 LINES中有 ITEM: LINE_NUMBER。要求当记录被删除时, LINE_NUMBER要重
新编号。
步骤 1 创建 ITEM的 HANDLER
步骤 2 创建自定义的TRIGGER:RESEQ_LINE_NUMBER
汉得信息技术有限公司 ORACLE应用开发培训手册
Lesson 9 FORM中对象的编程 37
Company Confidential -For internal use only
lines.lin e_number_seq :=lines.line_number_seq + 1;
:lines.line_number :=lines.line_number_seq;
步骤 3 调用 ITEM的 HANDLER
Trigger: KEY– DELETE:
lines.line_number(’KEY–DELETE’);
这个行号的特点是:
实现这样的行号相对比较麻烦,下面描述如何来实现上图中所示的行号功能:
各触发器的HANDLER:
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/22816976/viewspace-1442564/ ,如需转载,请注明出处,否则将追究法律责任。