我用谷歌搜索了这个,但不幸的是,找不到任何解决方案。
我有一个简单的表单(Oracle Forms Builder 10g),只有一个块。表单以Oracle EBS样式编写,也就是说,该块基于一个视图,该视图提取基表字段以及rowid和DML事件(插入时,更新后等触发器)由表处理程序处理封装
我想要添加的功能如下:当用户创建新记录时,表单会自动为表单中的所有字段建议值。因此,我创建了一个WHEN-CREATE-RECORD触发器,用于计算字段值并分配它们。除主键之外的所有键都基于序列并由包处理。
当我创建新记录时,一切都运行正常,但是当我尝试保存它时,我得到的只是FRM-40401"没有保存更改"错误,没有任何反应。
我试图跟踪错误,似乎表单将记录视为NEW而没有更改。即使我尝试将记录状态显式更改为INSERT,也会发生这种情况。
我已经尝试将默认行为更改为STANDARD.COMMIT(为此创建了一个ON-COMMIT触发器),但这并未修改任何内容。
为了记录,我尝试使表格基于表格,摆脱表格处理程序并将所有DML保留给表单。我还是得到了FRM-40401。
我无法理解出了什么问题,有什么想法吗?
答案 0 :(得分:1)
when-create-record
触发器完成后,记录状态将重置为NEW。这通常是有道理的,因为您有效地设置了项目的默认值,但用户实际上还没有输入任何数据。
在触发器完成后,您需要在上标记插入的记录 - 通常用户在将某些数据输入记录时会执行此操作。如果您希望用户能够保存记录而不更改其中的任何内容,您可以在保存按钮中添加一些内容以执行不变更改,例如。
:MYBLOCK.ANYITEM := :MYBLOCK.ANYITEM;
这会导致记录被标记为插入。
答案 1 :(得分:0)
好的,暂时我使用了经典的TIMER解决方法,一切正常:
PACKAGE body form_timers IS
PROCEDURE CREATE_NEW_RECORD;
procedure do_create(name varchar2) is
timer_id TIMER;
Begin
timer_id := CREATE_TIMER(name,1,NO_REPEAT);
End;
procedure expired is
expired_timer CHAR(20);
BEGIN
expired_timer:=GET_APPLICATION_PROPERTY(TIMER_NAME);
IF expired_timer='CREATE_NEW_RECORD' THEN
CREATE_NEW_RECORD;
-- ELSIF expired_timer='T2' THEN
-- /* handle timer T2 */ NULL;
ELSE
NULL;
END IF;
END;
PROCEDURE CREATE_NEW_RECORD IS
/* create record logic goes here */
END;
END;
......但是,我仍然想知道为什么会出现这种情况。