oracle视图触发器问题

hemingwang0902 2009-12-28 11:23:19
问题是这样的我现在有两个表 table_a 和 table_b, 还有一个视图 view_a, 表和视图的结构如下

-- Create table
create table table_a
(
a number,
b varchar2(30),
c varchar2(30)
);
-- Create/Recreate primary, unique and foreign key constraints
alter table table_a
add constraint PK_table_a primary key (A);

===================================================================

-- Create table
create table table_b
(
a number,
b varchar2(30),
c varchar2(30)
);
-- Create/Recreate primary, unique and foreign key constraints
alter table table_b
add constraint PK_table_b primary key (A);

===================================================================

create view view_a as select * from table_b;


但我对 table_b 没有任何操作权限,只对 table_a 和 view_a 有操作权限, 我现在要实现的功能是 table_b 中的数据有变化(inser, update, delete)时,就将 table_a 中的记录对应更新, 于是建立了下面这个触发器:

create or replace trigger trg_insurance
instead of update or insert or delete on view_a
begin
if inserting then
insert into table_a(a,b,c) values(:new.a,:new.b,:new.c);
elsif updating then
if (:new.b=1) then
insert into table_a(a,b,c) values(:new.a,:new.b,:new.c);
elsif (:new.b=0) then
delete from table_a where a=:old.a;
end if;
elsif deleting then
delete from table_a where a=:old.a;
end if;
end;

现在问题就来了, 对方(有权限操作table_b的)执行

//将 insert 改为对应的 update, delete 语句时一样不会触发
insert into table_b values(1,'1','1');
commit;

时,并没有触发触发器 trg_insurance, 而只有执行

//将 insert 改为对应的 update, delete 语句时也会执行触发器trg_insurance
insert into view_a values(1,'1','1');
commit;

时,触发器 trg_insurance 才会执行.

也就是说只有直接在 view_a 上作对应的操作时触发器 trg_insurance 才会被执行, 而直接操作实体表 table_b 时,触发器无法被执行, 请问我该怎么创建触发器才能在直接对实体表的数据进行修改(insert, update, delete)时,才能将触发器 trg_insurance 触发。(特别注意的是,我对 table_b 没有任何权限, 所以不可能直接在 table_b 上创建触发器)
...全文
544 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
runbaobao88 2009-12-28
  • 打赏
  • 举报
回复
补充6楼的:即使对基本表有操作权限,一样不能通过视图触发器来触发
ojuju10 2009-12-28
  • 打赏
  • 举报
回复
视图是基本表的虚表,操作视图就是操作基本表,
你对基本表table_b没有操作权限,所以你在触发器上建立触发器不成功
crazylaa 2009-12-28
  • 打赏
  • 举报
回复
没有权限应该是没有办法得。
runbaobao88 2009-12-28
  • 打赏
  • 举报
回复
补充:如果table_b是别人的东西,你没法在其中加触发器的话,你试试用这种思路。

建立一个table_c
1. 第一次将view_a中的内容拷贝到table_c
2.后续比较table_c(实际上就是view_a的早前内容)和view_a,根据这个差异更改你的table_a
这个方案的缺点是实时性不够好。
runbaobao88 2009-12-28
  • 打赏
  • 举报
回复
做不到的。
因为你只是针对view建立的触发器,view说到底就是一个预先编译过的执行计划而已。所以针对底层的表做操作的时候,view是感知不到的,这时候的view是一个死的东西。view只有有人用的时候,它才活过来,只有针对view做操作的时候,它才能感知到。
fatfoxz 2009-12-28
  • 打赏
  • 举报
回复
对table_b没有任何权限的话,应该就不能监控table_b上的事件了,而根据VIEW_A也无法判断table_b是否有数据修改,所以我觉得这个要求做不了
thesecretblue 2009-12-28
  • 打赏
  • 举报
回复
将 insert 改为对应的 update, delete 语句时也会执行触发器trg_insurance
insert into view_a values(1,'1','1');
commit;

3,491

社区成员

发帖
与我相关
我的任务
社区描述
Oracle 高级技术相关讨论专区
社区管理员
  • 高级技术社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧