求教Oracle数据库,表的行级触发器(涉及一连串的触发)。先网问题,紧急求助!!!急!!!
场景:一共3张表,用A,B,C表示。两个触发器,用W,Y表示。触发器都是行级触发 AFTER INSERT OR UPDATE FOR EACH ROW
在插入或更新A表数据后,使用A表触发器W在B表插入一条记录,在B表插入的数据中有一个字段为A表的关键字。
在插入或更新B表数据后,使用B表触发器Y在C表再插入一条数据,C表的大部分字段都是A表新插入记录的字段值。
(听起来似乎有点繁琐,但由于涉及3个厂家,A,B,C表分别在3个数据库上,是使用数据库链接来实现的)
问题:每次插入或更新C表的数据都落后了一步,即实际插入C表的数据都是A表OLD的值。
对问题自己的理解:自己调试,发现在C表的触发器Y中,使用查询语句select * from A where A.关键字=NEW.xxx。(xxx是B表的字段,其值为A表新插入的关键字)查询出来的记录还是更新前的数据。
似乎是在执行触发器Y中,A表的插入记录并没有提交。
我不知道我的这种理解对不对?另外使用触发器是否能实现我的这种需求啊?万分感谢大家提出宝贵意见!!!
场景:一共3张表,用A,B,C表示。两个触发器,用W,Y表示。触发器都是行级触发 AFTER INSERT OR UPDATE FOR EACH ROW
在插入或更新A表数据后,使用A表触发器W在B表插入一条记录,在B表插入的数据中有一个字段为A表的关键字。
在插入或更新B表数据后,使用B表触发器Y在C表再插入一条数据,C表的大部分字段都是A表新插入记录的字段值。
(听起来似乎有点繁琐,但由于涉及3个厂家,A,B,C表分别在3个数据库上,是使用数据库链接来实现的)
问题:每次插入或更新C表的数据都落后了一步,即实际插入C表的数据都是A表OLD的值。
对问题自己的理解:自己调试,发现在C表的触发器Y中,使用查询语句select * from A where A.关键字=NEW.xxx。(xxx是B表的字段,其值为A表新插入的关键字)查询出来的记录还是更新前的数据。
似乎是在执行触发器Y中,A表的插入记录并没有提交。
我不知道我的这种理解对不对?另外使用触发器是否能实现我的这种需求啊?万分感谢大家提出宝贵意见!!!
解决方案 »
- 初学Oracle,请教个各位老师们个题目,感激不尽
- 做oracle 10g 数据库的管理都有什么要学的呢?请前辈们赐教!!
- 请问oracle存数过程种where子句种需要有if判断的应该怎么写啊
- orcle 触发器 对某一个部门的某个职工涨工资 要求把该部门的职工都涨相同数目
- 关于10g left join 的新写法
- 如何知道一个表哪个字段是主键?在线等...
- 关于Oracle的序列问题,请各位大虾们帮忙,高分相送
- 请介绍sql语言好书
- 我想把满足一个条件的一些记录加 1 SQL语法是什么?请不要太复杂,谢谢。
- 菜鸟菜问,急,急,急,急需帮忙
- 数据库导入,保留额外字段
- oracle 锁问题???
会有问题,列出所有字段应该可以。
SQL> create table a(id number primary key,name varchar2(10));表已创建。SQL> create table b(id number primary key,name varchar2(10));表已创建。SQL> create table c(id number primary key,name varchar2(10));表已创建。SQL> create or replace trigger w
2 after insert or update on a
3 for each row
4 declare
5 begin
6 if inserting then
7 insert into b values(:new.id,:new.name);
8 end if;
9 end;
10 /触发器已创建SQL> create or replace trigger y
2 after insert or update on b
3 for each row
4 declare
5 begin
6 if inserting then
7 insert into c select * from a where id=:new.id;
8 end if;
9 end;
10 /触发器已创建SQL> insert into a values(1,'test');
insert into a values(1,'test')
*
ERROR 位于第 1 行:
ORA-04091: 表 CHENNAN.A 发生了变化,触发器/函数不能读
ORA-06512: 在"CHENNAN.Y", line 4
ORA-04088: 触发器 'CHENNAN.Y' 执行过程中出错
ORA-06512: 在"CHENNAN.W", line 4
ORA-04088: 触发器 'CHENNAN.W' 执行过程中出错
SQL> create or replace trigger y
2 after insert or update on b
3 for each row
4 declare
5 begin
6 if inserting then
7 insert into c values(:new.id,:new.name);
8 end if;
9 end;
10 /触发器已创建SQL> insert into a values(1,'test');已创建 1 行。SQL> select * from a; ID NAME
---------- ----------
1 test已选择 1 行。SQL> select * from b; ID NAME
---------- ----------
1 test已选择 1 行。SQL> select * from c; ID NAME
---------- ----------
1 test已选择 1 行。SQL>
这样用不行.表A属于变异状态..也就是常说的变异表
改为1楼那样就哦了..
楼主的意思是更新后C表插入的是旧值?
我写了个测试过,没问题:
SQL> create table a(id number primary key,name varchar2(10));表已创建。SQL> create table b(id number primary key,name varchar2(10));表已创建。SQL> create table c(id number primary key,name varchar2(10));表已创建。SQL> create or replace trigger w
2 after insert or update on a
3 for each row
4 declare
5 begin
6 if inserting then
7 insert into b values(:new.id,:new.name);
8 elsif updating then
9 update b set name=:new.name where id=:old.id;
10 end if;
11 end;
12 /触发器已创建SQL> create or replace trigger y
2 after insert or update on b
3 for each row
4 declare
5 begin
6 insert into c values(:new.id+1,:new.name);
7 end;
8 /触发器已创建SQL> insert into a values(1,'test');已创建 1 行。SQL> select * from a; ID NAME
---------- ----------
1 test已选择 1 行。SQL> select * from b; ID NAME
---------- ----------
1 test已选择 1 行。SQL> select * from c; ID NAME
---------- ----------
1 test已选择 1 行。SQL> update a set name='update' where id=1;已创建 1 行。SQL> select * from a; ID NAME
---------- ----------
1 update已选择 1 行。SQL> select * from b; ID NAME
---------- ----------
1 update已选择 1 行。SQL> select * from c; ID NAME
---------- ----------
1 test
2 update已选择 1 行。
在C表中就可以看到那个第二条数据"update"就是A表中更新后的值!
加上了自冶事务,select前加上commit也没用
后来又想通过视图触发器来做,这样就可以用:NEW了
我的看法
这个可能是触发器的事务原因,第一个触发器发起后,这时数据是脏数据,还没有提交,取不到最新的数据(脏数据)一串的触发器是同一个事务,只有最后一个触发器完成后才提交写入库,这是select才取到最近的数据。所以是没办法select取到第一个触发器更新的数据的第一个触发器发起是父事务,后面的是子事务,只有父事务提交了才行不知道是不是这样,没有查过文档,个人猜想