– 临时表就是用来暂时保存临时数据(亦或叫中间数据)的一个数据库对象,它和普通表有些类似,然而又有很大区别。它只能存储在临时表空间,而非用户的表空间。ORACLE临时表是会话或事务级别的,只对当前会话或事务可见。每个会话只能查看和修改自己的数据。

–ON COMMIT DELETE ROWS
–它是临时表的默认参数,表示临时表中的数据仅在事物过程(Transaction)中有效,当事物提交(COMMIT)后,临时表的暂时段将被自动截断(TRUNCATE),但是临时表的结构 以及元数据还存储在用户的数据字典中。如果临时表完成它的使命后,最好删除临时表,否则数据库会残留很多临时表的表结构和元数据。

– ON COMMIT PRESERVE ROWS
–它表示临时表的内容可以跨事物而存在,不过,当该会话结束时,临时表的暂时段将随着会话的结束而被丢弃,临时表中的数据自然也就随之丢弃。但是临时表的结构以及元数据还存储在用户的数据字典中。如果临时表完成它的使命后,最好删除临时表,否则数据库会残留很多临时表的表结构和元数据。
–1:会话级的临时表的数据和你当前会话有关系,当前SESSION不退出的情况下,临时表中的数据就还存在,临时表的数据只有当你退出当前SESSION的时候才被截断(TRUNCATE TABLE)

CREATE GLOBAL TEMPORARY TABLE TMP_TEST
 (
     ID NUMBER ,
     NAME VARCHAR2(32)
 ) ON COMMIT PRESERVE ROWS;CREATE GLOBAL TEMPORARY TABLE TMP_TEST ON COMMIT PRESERVE ROWS
 AS
 SELECT * FROM TEST;
 INSERT INTO TMP_TEST
 SELECT 1, ‘kerry’ FROM DUAL;COMMIT;
SELECT * FROM TMP_TEST;
 INSERT INTO TMP_TEST
   SELECT 2, ‘rouce’ FROM DUAL;
 SELECT * FROM TMP_TEST;

–事务级的临时表(默认),这种类型的临时表与事务有关,当进行事务提交或者事务回滚的时候,临时表的数据将自行截断,即当COMMIT或ROLLBACK时,数据就会被TRUNCATE掉,其它的特性和会话级的临时表一致

CREATE GLOBAL TEMPORARY TABLE TMP_TEST
 (
     ID NUMBER ,
     NAME VARCHAR2(32)
 ) ON COMMIT DELETE ROWS;CREATE GLOBAL TEMPORARY TABLE TMP_TEST ON COMMIT DELETE AS SELECT * FROM TEST;
 INSERT INTO TMP_TEST SELECT 1, ‘kerry’ FROM DUAL;
 SELECT * FROM TMP_TEST;
 COMMIT;

–关于临时表只对当前会话或事务可见。每个会话只能查看和修改自己的数据。
–用DM用户登录数据库,打开SESSION 1后,创建临时表TMP_TEST

CREATE GLOBAL TEMPORARY TABLE TMP_TEST
 (
     ID NUMBER ,
     NAME VARCHAR2(32)
 ) ON COMMIT DELETE ROWS;
 CREATE GLOBAL TEMPORARY TABLE TMP_TEST ON COMMIT DELETE AS SELECT * FROM TEST;CREATE GLOBAL TEMPORARY TABLE TMP_TEST
 (
     ID NUMBER ,
     NAME VARCHAR2(32)
 ) ON COMMIT DELETE ROWS;INSERT INTO TMP_TEST
    SELECT 1, ‘kerry’ FROM DUAL;
 SELECT * FROM TMP_TEST;
 COMMIT;SELECT * FROM TMP_TEST;
 SELECT * FROM DBA_TABLES WHERE TABLE_NAME=‘TMP_TEST’ --可以查到临时表数据
 SELECT * FROM DM.TMP_TEST; --查不到数据,即使TMP_TEST临时表存在数据。

–与永久表区别
–临时表的DML操作速度比较快,但同样也是要产生 Redo Log ,只是同样的DML语句,比对 PERMANENT 的DML 产生的Redo Log 少其实在应用中,往往会创建一个NOLOGGING的永久表(中间表)来保存中间数据,从而代替临时表,至于这这两者有啥优劣,真是很难说清道明(欢迎大家探讨)。

–用途
–1:当处理某一批临时数据,需要多次DML操作时(插入、更新等),建议使用临时表。
–2:当某些表在查询里面,需要多次用来做连接时。(为了获取目标数据需要关联A、B、C, 同时为了获取另外一个目标数据,需要关联D、B、C…)
–关于临时表和中间表(NOLOGGING,保存中间数据,使用完后删除)那个更适合用来存储中间数据,我个人更倾向于使用临时表,而不建议使用中间表。

–注意事项
–不支持 lob 对象,这也许是设计者基于运行效率的考虑,但实际应用中确实需要此功能时就无法使用临时表了。这点网上很多资料都这么说,我没有追查到底是那个版本不支持lob对象,至少在ORACLE 10g这个版本中,临时表是支持lob对象的.

CREATE GLOBAL TEMPORARY TABLE TMP_TEST
 (
 ID NUMBER ,
 NAME CLOB
 ) ON COMMIT PRESERVE ROWS;INSERT INTO TMP_TEST
 SELECT 1, ‘ADF’ FROM DUAL;
 SELECT * FROM V$VERSION;

–不支持主外键关系

–临时表不能永久的保存数据。

–临时表的数据不会备份,恢复,对其的修改也不会有任何日志信息

–临时表不会有DML 锁

–尽管对临时表的DML操作速度比较快,但同样也是要产生 Redo Log ,只是同样的DML语句,比对 PERMANENT 的DML 产生的Redo Log 少。请见官方文档

– 临时表可以创建临时的索引、视图、触发器。

–如果要DROP会话级别临时表,并且其中包含数据时,必须先截断其中的数据。否则会报错。

– 试图创建, 更改或删除正在使用的临时表中的索引