首先说明我要实现的功能:假设A表和B表,我想实现,在增加A表的同时,利用刚刚插入的数据和A表中已有的数据(包括刚刚插入的数据)进行如数据编码(code)组合,生成一个新的字符串插入到B表中的编码列;
我使用的Oracle客户端是PL/SQL devloper 8,
我现在想到的方案:
方案1:使用行触发器,在插入的时候使用new获取刚刚插入的数据,这样跟之前已经有的数据组合,但是这样当插入两条或多条的时候,会出现下一条总是无法和刚刚插入的数据组合,也就是不能发现同一批插入的数据;(按道理,两个SQL语句应该是两个事务,应该能使用刚刚插入的数据,这是第一个疑问,是不是客户端造成的,我的客户端设置是自动提交SQL,不应该有问题)
方案2:在第一种方案不能满足需求,我寻求了第二种方案,就是建立一个全局临时表,然后使用行触发器把新插入的数据放到临时表中,再最后做一次语句触发器,在语句级触发器中使用游标遍历临时表记录,跟已经存在的数据进行组合,插入到B表中;(疑问2:在插入多条数据的时候,比如两个insert语句,行触发器在临时表新增一条数据,然后触发了一次语句级触发器,然后行触发器在临时表又新增一条数据,然后又触发了一次语句级触发器,跟我预想的应该是两次行触发器,一次最终语句级触发不一样,不知道是不是我理解的不对;按照我的理解,两个insert语句应该是两个事务,这样临时表只会保留一条记录,但是目前确实是多条;如果两条insert在一个事务内,为什么又多次触发语句级触发器?);目前解决方法就是在语句触发器最后增加一条删除临时表数据,这样保证临时表始终是最新插入的数据。代码如下:
CREATE TABLE A ( id number, name varchar2(30), birthdate date ) ;
-- B表 CREATE TABLE B ( id number, name varchar2(30), birthdate date ) ;
-- 创建临时表 a_tt,存储刚刚插入的数据 CREATE global temporary TABLE a_tt (id number, name varchar2(30), birthdate date ) ON COMMIT DELETE ROWS;
--A表的行触发器记录新插入的数据 create or replace trigger a_insert_row AFTER insert on A for each row declare begin insert into a_tt(id,name,birthdate) values(:new.id,:new.name,:new.birthdate); end;
create or replace trigger aaaa_insert_tt AFTER insert on A declare v_name aaaa_log.name%type; cursor n_cur is select name from a_tt; begin dbms_output.put_line('语句触发器执行'); for cur in n_cur loop dbms_output.put_line( cur.name); insert into B(name) select cur.name ||'_' ||name from A; end loop; -- delete from a_tt; --删除临时表过时数据 end;
测试语句:
insert into A values(2,'a',sysdate);
insert into A values(3,'b',sysdate);
预期结果:B表中name 列 2_2,3_2,3_3
希望各位大神,帮我理理思路,不知道我说清没有
触发器执行的时候是不是在行触发器(after)之后提交数据,在语句级触发器就可以使用提交后的数据