Oracle Form 之 Compute Data

操作数据无非删除、更新、插入的动作,在Oracle Form依靠下面触发器完成这些操作。
Form Trigger
Key-commit        保存按钮触发/Ctrl+S 键盘触发/代码触发
Block Trigger
Pre-delete        Pre-update        Pre-insert
On-delete        On-update        On-insert        On-lock

Oracle保存数据的机制:第一步依次从数据库中删除在Block上删除的记录(删除每条记录时先触发Pre-delete,再触发On-delete),第二步依次从数据库中更新在Block上更新的记录(更新每条记录时先触发Pre-update,再触发On-update),第三步依次向数据库中插入在Block上插入的记录(插入每条记录时先触发Pre- insert,再触发On- insert),第四步COMMIT。其中任何一步出错的话都会引发异常,回滚以前的操作。

        如果限制Form在一定条件下才允许保存,可以将控制逻辑写在Form级trigger pre-commit或者block级的Pre-delete,Pre-update,Pre-insert代码中(这种情况控制可以针对操作类型进行控制,更加精细),一但条件不满足,立即抛出异常或忽略本次操作。

        On-lock触发器在用户在界面上企图修改数据时触发,利用了Oracle悲观封锁的机制,保证数据的完整性和一致性。

在需要设置who字段的block中,Pre-insert和Pre-update都要添加如下代码:
fnd_standard.set_who;

oracle会调用API给那几个who字段赋值,不用我们操心了。
另外在pre-insert的触发器中设置某些 Item 的初始值,比如说给org_id字段赋值,比如给一个主键 Item赋一个sequence.nextval,这样与在Item的initial value属性中设定sequence.nextval
相比可以节省很多序列号,也可以更好保证序列号的连续性,这在某些业务中是非常关键的。

Eg:
:BLOCKNAME.ITEM_NAME := FND_PROFILE.VALUE(‘VALUE_NAME’);
SELECT SEQUENCE_A.NEXTVAL INTO :BLOCKNAME.ITEM_NAME ;

        操作数据前提是设置Block的Insert_Allowed,Update_Allowed,Delete_Allowed属性为Yes,对于数据源为基表,单表视图或简单多表视图,可以利用Oracle Form自身的机制,不需借助任何代码,可以实现数据的操作。

1.操作基表和单表视图

Block
PropertyValue Note
DML Data Target Type Table

2.操作多表视图

Block
PropertyValueNote
DML Data Target TypeTable
DML Data Target NameTable_Name操作的基表名
Item(主键字段)
PropertyValueNote
Primary KeyYes不指定主键的话编译会出错

以上2种情况,系统会自动构造Insert,Update,Delete,Lock语句。根据我Trace的结果来看,
Update,Delete,Lock都是根据记录的ROWID来唯一确认一条记录的。

3.使用代码操作数据

        对于数据的操作,建议用代码实现,这样比较直观,出了问题也容易找到原因。Oracle Form会分别调用ON-INSERT触发,ON-UPDATE触发,ON-DELETE触发分别完成插入、更新、删除操作。需要注意的是:在符合上面1,2类型的情况下,创建了ON-XXXXXX触发器,里面的代码为NULL;这时候系统就不能自动操作数据了,因为Oracle Form检测到了ON-XXXXXX触发器,执行了其中的代码,即执行了 NULL;语句。

Procedure Insert_Row Is
    Cursor c Is
        Select Return_Fix_Headers_Id
          From Tvsn_Return_Fix_Headers_All
         Where Return_Fix_Headers_Id = :Header.Return_Fix_Headers_Id;
Begin
    Insert Into Tvsn_Return_Fix_Headers_All
        (Return_Fix_Headers_Id,
         Line_Type,
         Order_Header_Id,
         f_To_r_Flag,
         Org_Id,
         Creation_Date,
         …,
         Attribute15)
    Values
        (:Header.Return_Fix_Headers_Id,
         :Header.Line_Type,
         :Header.Order_Header_Id,
         :Header.f_To_r_Flag,
         :Parameter.g_Org_Id,
         :Header.Creation_Date,
         …,
         :Header.Attribute15);
    Open c;
    Fetch c
        Into :Header.Return_Fix_Headers_Id;
    If (c%Notfound)
    Then
        Close c;
        Raise No_Data_Found;
    End If;

    Close c;
End Insert_Row;
Procedure Update_Row Is
Begin
    Update Tvsn_Return_Fix_Headers_All
       Set Return_Fix_Headers_Id = :Header.Return_Fix_Headers_Id,
           Line_Type             = :Header.Line_Type 14,
           Order_Header_Id       = :Header.Order_Header_Id,
           f_To_r_Flag           = :Header.f_To_r_Flag,
           Org_Id                = :Header.Org_Id,
           Creation_Date         = :Header.Creation_Date,
           …                   ,
           Attribute15           = :Header.Attribute15
     Where Return_Fix_Headers_Id = :Header.Return_Fix_Headers_Id;
    If (Sql%Notfound)
    Then
        Raise No_Data_Found;
    End If;

End Update_Row;
Procedure Delete_Row Is
Begin
    Delete From Tvsn_Return_Fix_Headers_All
     Where Return_Fix_Headers_Id = :Header.Return_Fix_Headers_Id;
    If (Sql%Notfound)
    Then
        Raise No_Data_Found;
    End If;

End Delete_Row;

以上3段代码是很经典的插入,修改,删除语句。特点是每次操作完成之后都有一个检验过程,红色语句。可以将这些代码放在数据库,pll文件,form的program unit,甚至是直接写在trigger 中,从性能的角度出发可能放在数据库中更高效,综合维护方便等因素考虑,建议写在orm的program unit中。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值