会话临时表 ORA-14452

需要使用Oracle的临时表,向其中插入记录,用完后再删除。但是后来发现临时表的删除总是失败,返回错误:

ORA-14452: attempt to create, alter or drop an index on temporary table already in use

这个错误是Oracle的临时表设计原理造成。在Oracle中,临时表是同session绑定在一起的,准确的说,是表中的数据及相关的事物是同 session绑定的,这个绑定是从session首次向表中插入数据开始的。不同的session可以向同一个临时表中插入记录,提交事务,但是即使在 提交事务之后,不同的session从同一个临时表中选出的数据也是不一样的——一个session只能选出自己插入的数据。

临时表在会话结束后会被truncate,当然,truncate也不会影响其它的会话。这个操作解除了临时表同当前会话之间的关系,只有这样,才能使用drop语句删除临时表。不过如果此时还有其它会话在使用这个临时表,那么drop操作自然也会失败。

上面所说的情况是针对使用 CREATE GLOBAL TEMPORARY TABLE XXXX (......) on commit preserve rows 语句创建的临时表。

--------------------------------------------------------------------------------------------------------------------------------

1、数据库中的所有会话均可以访问同一临时表,但只有插入数据到临时表中的会话才能看到它本身插入的数据。

2、可以把临时表指定为事务相关(默认)或者是会话相关:

3、如果临时表中有记录的话,是无法删除表的。即无法drop table

4、虽然临时表不产生 "REDO" ,但却是要产生 "UNDO"

-----------------------------------------------------------------------------------------------------------------------------------------

 

 


1、删除会话特有的临时表

想快速删除此类临时表,必须先truncate表中的数据,然后drop表结构。如果使用DELETE命令先删除表中记录的话,还无法直接删除表。只有等当前会话退出后,在其它会话或新的会话中删除表结构。

使用DELTETEDROP表报错:

SQL> DELETE tmp_test;

8 rows deleted

SQL> commit;

Commit complete

SQL> drop table tmp_test;

ORA-14452: attempt to create, alter or drop an index on temporary table already in use

这是因为用“ON COMMIT PRESERVE ROWS”子句时,会加行锁(ROW-X).

TYPE=TO

TO Lock "Temporary Table Object Enqueue"

具体请看DOC ID:186854.1

 


2、删除事务特有的临时表

ON COMMIT DELETE ROWS 子句就不会有那么多限制。COMMIT以后,记录自动清除,可以直接就删除表。

 
临时表的表空间的分配

临时表在创建的时候,是不分配表空间的。当用户使用临时表存储数据时,从该用户默认的临时表空间来分配存储空间。

原文地址:https://www.cnblogs.com/zhangyabin---acm/p/3632734.html