Oracle事务临时表的一个隐藏问题

Oracle临时分为两类,
一类是事务临时表,以on commit delete rows指示。按照指示含义,我们可以知道这类临时表数据是在commit之后就清除数据的。
一类是session临时表,以on commit preserve rows指示。同样,按照含义,表明这类表在commit之后还是保留数据的(直到session结束后会被自动清除)。
为什么要提Oracle的这两类临时表呢?他们的属性就这么点,还有啥好提的?呵呵。看下面例子:
--先创建一个事务临时表:
create global temporary table xxx(x int) on commit delete rows;
--执行如下语句:
SQL> declare
  2      cursor cx is
  3      select * from xxx;
  4      type typ_cx is table of cx%rowtype index by pls_integer;
  5      v_cx typ_cx;
  6  begin
  7      insert into xxx
  8      select rownum from dual connect by rownum <= 20000;
  9      open cx;
 10      loop
 11          fetch cx bulk collect into v_cx limit 3000;
 12          exit when v_cx.count = 0;
 13          dbms_output.put_line('Count: ' || v_cx.count);
 14          commit;
 15      end loop
 16      commit;
 17  end;
 18  /
发生报错:
ORA-01410: invalid ROWID
ORA-06512: at line 12
觉得正常吗?
现在删除该临时表,创建一个session级的临时表,其他都不变:
--删除临时表
drop table xxx
--创建session临时表
create global temporary table xxx(x int) on commit preserve rows;
--执行之前那个过程
SQL> declare
  2      cursor cx is
  3      select * from xxx;
  4      type typ_cx is table of cx%rowtype index by pls_integer;
  5      v_cx typ_cx;
  6  begin
  7      insert into xxx
  8      select rownum from dual connect by rownum <= 20000;
  9      open cx;
 10      loop
 11          fetch cx bulk collect into v_cx limit 3000;
 12          exit when v_cx.count = 0;
 13          dbms_output.put_line('Count: ' || v_cx.count);
 14          commit;
 15      end loop
 16      commit;
 17  end;
 18  /
 
PL/SQL procedure successfully completed
执行成功!!这是为什么?
看代码知道,这个过程就是将20000个数字的数据插入到临时表,然后打开临时表的游标,将这些数字以每批3000分批从游标中取出并打印对应批次的数量。打印后,执行一个commit命令。问题就出在这个commit命令上,因为commit表示一个提交,而事务临时表在commit之后,数据随之被清空,导致下次fetch游标中的数据时无法取到,从而发生第一个过程执行时的错误。而session临时表就不会有这个问题。
另外,需要注意的是,session临时表是在整个session期间有效的,因此在同个session期间如果执行了多次,会重复的插入数据到该表中。开发的时候要注意这个现象,否则很容易出现累加效应。


来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/12932950/viewspace-682606/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/12932950/viewspace-682606/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值