oracle视图更新,替代触发器

来源:互联网 发布:pdfobject.js使用方法 编辑:程序博客网 时间:2024/05/17 20:31

在oracle中通常如果视图的数据源来自单表则该视图可以进行更新。而如果视图数据源来自两个以上表时这个视图是不可更新的。但有时候为了操作的方便我们更希望能够对多表视图也进行更新。

这时候我们可以通过建立更新触发器来替代该视图原有更新以达到多表更新的效果

例如:

3.1 创建测试数据表
--===================================================
--创建测试表
--===================================================
Drop Table t1;
Drop Table t2;
create table t1
( t11 numeric(28),t12 varchar2(20));
create table t2
( t11 numeric(28),t22 varchar2(20));

3.2 多表视图范例
--===================================================
--创建测试视图
--===================================================
create Or Replace view t as
   select T1.t11 f1 ,T1.t12 f2 ,T2.t22 f3
      from T1,T2 
      Where T1.t11=T2.t11;

3.3 多表视图触发器范例      
--===================================================
--创建视图的替代触发器
--===================================================
Create Or Replace Trigger Trg_InsUpdDel_t
  Instead Of Insert or update or delete
  on t
  for each row
Declare
begin
   If Inserting Then
      Insert Into t1 (t11,t12) Values (:New.f1,:New.f2);
      Insert Into t2 (t11,t22) Values (:New.f1,:New.f3);
   elsif Updating Then
      Update t1 set t11=:New.f1,t12=:New.f2 where t11=:New.f1;
      Update t2 set t11=:New.f1,t22=:New.f3 where t11=:New.f1;
   elsif Deleting then
      Delete from t1 where t11=:Old.f1;
      Delete from t2 where t11=:Old.f1;
   End if;
end;
如此即实现多表可更新视图的定义工作 

但要注意当视图进行重新编译的时候这个触发器会失效需要重建。



替代触发器

当执行数据库视图的更新时,就能触发替代触发器。大家都知道,数据库视图可认为是派生表。当查询一个视图时,事实上是查询了一个或多个基础表。当更新视图时,事实上更新了基础表。然而,不是所有视图都能轻易更新的,在某些情况下,Oracle服务器不知道如何处理更新,就会报错:你所工作的视图不可更新。替代触发器用过程代码替代了触发语句。下面是相关示例。

  假设你想要把会计部门的平均工资减少2%的额度(这明显是个假设的例子)。
  该视图是不可更新的。Oracle服务器不能指出哪个员工(或哪些员工)应该被调整,以改变部门的平均工资。替代触发器可以提供所需的逻辑。例如,我们可以把部门里的薪资调整平均地放到每一个员工身上。
  注意 DNAME列用来访问dept行。为了避免出现问题,DNAME列应该被声明为唯一。
  替代触发器类似于DML行触发器,它对每行都产生影响,并能访问:OLD和:NEW值。
  因为我们创建了更新触发器,而不是INSERT或DELETE触发器,所以无法对该视图执行插入或删除。
  当讨论到开启版本功能的(version-enabled)表时,还会再回到替代触发器。