Oracle临时表是一类特殊的表,Oracle临时表(Temporary table)用于保存事务或会话期间的中间结果集。下面就为您详细介绍Oracle临时表相关的知识,供您参考。
临时表中保存的数据只对当前会话可见,所有会话都看不到其他会话的数据;临时表比常规表生成的redo少得多。不过,由于临时表必须为其中包含的数据生成undo信息, 所以也会生成一定的redo。 UPDATE和DELETE会生成最多的undo; INSERT和SELECT生成的undo最少。
对于Oracle临时表,运行时当一个会话第一次在临时表中放入数据时,才会为该会话创建一个临时段。由于每个会话会得到其自己的临时段(而不是一个现有段的一个区段),每个用户可能在不同的表空间为其临时表分配空间。
Oracle临时表与其他关系数据库中的临时表类似,这样区别只是:Oracle临时表是“静态”定义的。每个数据库只创建一次临时表,而不是为数据库中的每个存储过程都创建一次。在Oracle中,临时表一定存在,它们作为对象放在数据字典中,但是在会话向临时表中放入数据之前,临时表看上去总是空。由于临时表是静态定义的,所以你能创建引用临时表的视图,还可以创建存储过程使用静态SQL来引用临时表,等等。临时表可以是基于会话的(临时表中的数据可以跨提交存在,即提交之前仍然存在,但是断开连接后再连接后再连接时数据就没有了),也可以是基于事务的(提交之后数据就消失)。下面这个例子显示了这两种不同的临时表。我使用SCOTT.EMP表作为一个模板:
- ops$tkyte@ORA10G> create global temporary table temp_table_session
- 2 on commit preserve rows
- 3 as
- 4 select * from scott.emp where 1=0
- 5 /
- Table created.
ON COMMIT PRESERVE ROWS 子句使得这是一个基于会话的临时表。在我的会话断开连接之前,或者我通过一个DELETE或TRUNCATE物理地删除行之前,这些行会一直存在于这个临时表中。
- ops$tkyte@ORA10G> create global temporary table temp_table_transaction
- 2 on commit delete rows
- 3 as
- 4 select * from scott.emp where 1=0
- 5 /
- Table created.
ON COMMIT DELETE ROWS 子句使得这是一个基于事务的临时表。我的会话提交时,临时表中的行就不见了。只需把分配给这个表的临时区段交回,这些行就会消失,在临时表的自动清除过程中不存在开销。
如果你曾在SQL Server和/或 Sybase中用过临时表,现在所要考虑的主要问题是:不应该执行SELECT X, Y, Z INTO #TEMP FROM SOME_TABLE来动态创建和填充一个临时表,而应该:
l 将所有全局临时表只创建一次,作为应用安装的一部分,就像是创建永久表一样。
l 在你的过程中,只需执行INSERT INTO TEMP(X, Y, Z) SELECT X, Y, Z FROM SOME_TABLE。
归根结底,这里的目标是:不要在运行时在你的存储过程中创建表。这不是Oracle 中使用临时表的正确做法。DDL是一种代价昂贵的操作:你要全力避免在运行时执行这种操作。一个应用的临时表应该在应用安装期间创建,绝对不要在运行时创建。
Oracle临时表可以有永久表的许多属性。它们可以有触发器、检查约束、索引等。但永久表的某些特性在临时表中并不支持,这包括:
l 不能有引用完整性约束。临时表不能作为外键的目标,也不能在临时表中定义外键。
l 不能有 NESTED TABLE类型的列。 在 Oracle 9i及以前版本中, VARRAY类型的列也不允许;不过Oracle 10g中去掉了这个限制。
l 不能是 IOT。
l 不能在任何类型的聚簇中。
l 不能分区。
l 不能通过ANALYZE表命令生成统计信息。
在所有数据库中,临时表的缺点之一是优化器不能正常地得到临时表的真实统计。(
【编辑推荐】