ORACLE的临时表在应用系统中有很大的作用,它可以让用户只能够操作各自的数据中而互不干扰,不用担心会破坏或影响其他SESSION/TRANSACTION的数据,这也是数据安全的一种解决方法。 临时表分为SESSION、TRANSACTION两种,用法分别如下:
- 事务临时表——on commit delete rows
会话用户插入的数据将在事务提交后消失(truncate)。通过简单恢复分配到表的临时盘区,行就会消失。此过程不涉及额外开销。
create global temporary table TMP_TAB on commit delete rows;
create global temporary table tmp_t1(id number) on commit delete rows;
insert into tmp_t1 values (1);
select * from tmp_t1;
commit;select * from tmp_t1;
commit后再查询,刚刚插入的记录已经不存在了。一旦commit,自动删除transaction级临时表中的数据。
- 会话临时表——on commit preserve rows
会话用户插入的数据将保存在表中,数据在整个SESSION内有效;只到会话断开或通过delete或truncate删除数据。
create global temporary table TMP_TAB on commit preserve rows;
create global temporary table tmp_t2(id number) on commit preserve rows;
insert into tmp_t2 values (2);
select * from tmp_t2;
ID 2 此时结束SESSION,重新登录,再查询数据select *from tmp_t2,记录已经不存在。因为系统在结束SESSION时自动清除记录。
- 用同一个用户账号再开一个session,往tmp_t2中再插入一条记录然后查询。
insert into tmp_t2 values (3);
select * from tmp_t2;
ID 3 结果显示只能看到此session用户自己的记录。上一会话插入的“2”看不到。验证了临时表各自数据互不干扰的特性。
临时表的一些特性总结如下:
- 临时表用于保存事务或会话期间的中间结果;
- 临时表保存的数据只是对当前会话可见,任何会话不能看到其它会话的数据,即使是commit后也不可见;
- 临时表比正常表产生的redo少得多。但仍然会产生一些redo,并且无法消除;
- 临时表中insert和select时,产生的redo数量不值一提。只有当大量delete或update时,才会产生大量redo;
- 创建临时表后,总是存在的,它作为对象存储在数据库字典中,并且总是保持为空。知道有会话在其中放入数据;
- 避免在运行存储过程中创建表,因为DDL是一种消耗很大的操作。应在程序安装是创建,并通常创建全局临时表;
- 不要试图把一个大的查询“分成”较小的临时表查询;
- 临时表中不能用analyze来生成统计,然而可以通过dbms_stats包在临时表中设置;