这篇文章主要介绍了Oracle数据库中的临时表用法,但愿对你们的学习和工做有所帮助。 html
在Oracle中,能够建立如下两种临时表:
web(1) 会话特有的临时表
(2) 事务特有的临时表
所建的临时表虽然是存在的,可是若是insert 一条记录而后用别的链接登上去select,记录是空的。
--ON COMMIT DELETE ROWS 说明临时表是事务指定,每次提交后ORACLE将截断表(删除所有行)
--ON COMMIT PRESERVE ROWS 说明临时表是会话指定,当中断会话时ORACLE将截断表。 sql
create or replace procedure pro_temp(v_col1 varchar2,v_col2 varchar2) as v_num number; begin select count(*) into v_num from user_tables where table_name=''T_TEMP''; --create temporary table if v_num<1 then execute immediate ''CREATE GLOBAL TEMPORARY TABLE T_TEMP ( COL1 VARCHAR2(10), COL2 VARCHAR2(10) ) ON COMMIT delete ROWS''; end if; --insert data execute immediate ''insert into t_temp values ('''''' v_col1 '''''','''''' v_col2 '''''')''; execute immediate ''select col1 from t_temp'' into v_num; dbms_output.put_line(v_num); execute immediate ''delete from t_temp''; commit; execute immediate ''drop table t_temp''; end pro_temp;
测试:
数据库
临时表只在当前链接内有效
临时表不创建索引,因此若是数据量比较大或进行屡次查询时,不推荐使用
数据处理比较复杂的时候时表快,反之视图快点
在仅仅查询数据的时候建议用游标: open cursor for ''sql clause'';
安全
==================性能优化
1、数据库中的全部会话都可以访问同一临时表,但只有插入数据到临时表中的会话才能看到它自己插入的数据。oracle
2、能够把临时表指定为事务相关(默认)或者是会话相关:工具
3、若是临时表中有记录的话,是没法删除表的。即没法drop table。sqlserver
4、虽然临时表不产生 "REDO" ,但倒是要产生 "UNDO" 的post
记录将留在此表中,直到会话断开或经过DELETE或TRUNCATE从物理上删除这些记录。
CREATE GLOBAL TEMPORARY TABLE <TABLE_NAME> (<column specification> )
ON COMMIT PRESERVE ROWS;
当事务提交后,在事务之中插入的记录不会被保留,自动删除。
CREATE GLOBAL TEMPORARY TABLE <TABLE_NAME> (<column specification> )
ON COMMIT DELETE ROWS;
这里的“GLOBAL”表示临时表的定义,是全部会话都能看见的。创建临时表只有 CREATE GLOBAL TEMPORARY TABLE,而没有其它CREATE ****** TEMPORARY TABLE形式的命令。
想快速删除此类临时表,必须先truncate表中的数据,而后drop表结构。若是使用DELETE命令先删除表中记录的话,还没法直接删除表。只有等当前会话退出后,在其它会话或新的会话中删除表结构。
使用DELTETE后DROP表报错:
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
用ON COMMIT DELETE ROWS 子句就不会有那么多限制。COMMIT之后,记录自动清除,能够直接就删除表。
临时表在建立的时候,是不分配表空间的。当用户使用临时表存储数据时,从该用户默认的临时表空间来分配存储空间。
1、http://blog.itpub.net/post/10/8764
使用临时表的sql优化案例二-临时表的统计信息
2、http://www.itpub.net/178008.html&highlight=%C1%D9%CA%B1%B1%ED
抛砖引玉:三种主流数据库中临时表的使用.doc
MS SQLSERVER
SQL Server 支持临时表。临时表就是那些名称以井号 (#) 开头的表。若是当用户断开链接时没有除去临时表,SQL Server 将自动除去临时表。临时表不存储在当前数据库内,而是存储在系统数据库 tempdb 内。
临时表有两种类型:
本地临时表:本地临时表的名称以单个数字符号 (#) 打头;它们仅对当前的用户链接是可见的;当用户从 Microsoft SQL Server 2000 实例断开链接时被删除。
全局临时表:全局临时表的名称以数学符号 (##) 打头,建立后对任何用户都是可见的。若是在建立全局临时表的链接断开前没有显式地除去这些表,那么只要全部其它任务中止引用它们,这些表即被除去。当建立全局临时表的链接断开后,新的任务不能再引用它们。当前的语句一执行完,任务与表之间的关联即被除去;所以一般状况下,只要建立全局临时表的链接断开,全局临时表即被除去。
例如,若是建立名为 employees 的表,则任何人只要在数据库中有使用该表的安全权限就可使用该表,除非它已删除。若是建立名为 #employees 的本地临时表,只有您能对该表执行操做且在断开链接时该表删除。若是建立名为 ##employees 的全局临时表,数据表中的任何用户都可对该表执行操做。若是该表在您建立后没有其余用户使用,则当您断开链接时该表删除。若是该表在您建立后有其余用户使用,则 SQL Server在全部用户断开链接后删除该表。
如今,临时表的许多传统用途可由具备 table 数据类型的变量替换。
ORACLE
Oracle支持临时表。临时表用来保存事务或会话期间的中间结果。在临时表中保存的数据只有对当前会话是可见的,任何会话都不能看到其余会话的数据,即便在当前会话COMMIT数据之后也是不可见的。多用户并行不是问题,一个会话历来不阻塞另外一个会话使用临时表。即便锁定临时表,一个会话也不会阻塞其余会话使用临时表。临时表比正常表产生的REDO少得多,然而,因为临时表必须产生包含数据的UNDO信息,因此会产生必定数量的REDO日志。
临时表将从用户临时表空间的的目前日志中分配空间,或者若是从有定义权的程序中访问,将使用程序全部者的临时表空间。全局临时表实际上只是表自己的模板。建立临时表的行为不包括存储空间的分配,也不包括INITIAL的分配。所以,在运行时当一个会话首先将数据放到临时表中时,这时将建立这个会话的临时段。因为每一个会话获取本身的临时段,每一个用户可能在不一样的表空间中为临时表分配空间。USER1的default临时表空间为TEMP1,他的临时表将从TEMP1中分配空间,USER2的default临时表空间为TEMP2,他的临时表将从TEMP2中分配空间。
临时表在每一个数据库中只需建立一次,没必要在每一个存储过程当中建立。临时表老是存在的,除非手动的删除他。临时表做为对象存在数据字典中,而且老是保持为空,直到有会话在其中放入数据。Oracle容许建立基于临时表的视图和存储过程。
临时表能够是以会话为基础的,也能够是以事务为基础的。ON COMMIT PRESERVE ROWS子句使临时表成为基于会话的模式。行将留在此表中,直到会话断开或经过DELETE或TRUNCATE从物理上删除这些行。ON COMMIT DELETE ROWS子句使临时表成为基于事务的模式。当会话提交后,行消失。这个临时表的自动清除过程不会有额外的开销。
在oracle中,应用程序须要的临时表应该在程序安装时建立,而不是在程序运行时建立。(这是与ms sqlserver或sybase的使用的不一样)
在任何数据库中,临时表的一个缺点是:事实上优化器在临时表中没有真正的统计功能。然而,在oracle中,一系列较好的统计猜想能够经过DBMS_STATS包在临时表中设置。
DB2
可以使用 DECLARE GLOBAL TEMPORARY TABLE 语句来定义临时表。DB2的临时表是基于会话的,且在会话之间是隔离的。当会话结束时,临时表的数据被删除,临时表被隐式卸下。对临时表的定义不会在SYSCAT.TABLES中出现
下面是定义临时表的一个示例:
DECLARE GLOBAL TEMPORARY TABLE gbl_temp
LIKE empltabl
ON COMMIT DELETE ROWS
NOT LOGGED
IN usr_tbsp
此语句建立一个名为 gbl_temp 的用户临时表。定义此用户临时表 所使用的列的名称和说明与 empltabl 的列的名称和说明彻底相同。隐式定义 只包括列名、数据类型、可为空特性和列缺省值属性。未定义全部其余列属性,包括惟一约束、外部关键字约束、触发器和索引。执行 COMMIT 操做时, 若未对该表打开 WITH HOLD 游标,则该表中的全部数据都被删除。不记录 对用户临时表所做的更改。用户临时表被放在指定的用户临时表空间中。此表空间必须存在,不然此表的声明将失败。
户定义临时表不支持:
LOB 类型的列(或基于 LOB 的单值类型列)
用户定义类型列
LONG VARCHAR 列
DATALINK 列
End of document.
临时表是复杂SQL性能优化中常见手段,总结一下。
会话级的临时表
【语法】
【特色】
临时表数据自动清空后,可是临时表的结构以及元数据还存储在用户的数据字典中。表的定义对全部的会话可见。
临时表不须要DML锁。 www.2cto.com
能够索引临时表和在临时表基础上创建视图。
在临时表上的索引也是临时的,也是只对当前会话或者事务有效。
临时表能够拥有触发器。
能够用export和import工具导入导出临时表的定义,可是不能导出数据。
【适用场合】
当某一个SQL语句多表关联,而且和一些小表关联。能够采用将大表进行分拆而且获得比较小的结果集合存放在临时表中。
程序执行过程当中屡次使用的临时数据,这些数据在整个程序的会话过程当中都须要用的等等。
【清除时点】
当某一个SESSION退出以后自动清除数据(表结构保留)
【不足】
不支持lob对象,这也许是设计者基于运行效率的考虑,但实际应用中确实须要此功能时就没法使用临时表了。
不支持主外键关系。
例子:
CREATE GLOBAL TEMPORARY TABLE my_temporary (birthdate DATE, enddate DATE, name CHAR(20)) ON COMMIT PRESERVE ROWS;
事务级的临时表
【语法】
Create Global Temporary Table Table_Name
(the aggregation SQL statement) On Commit Delete Rows;
【清除时点】 当执行COMMIT以后自动清除数据(表结构保留)
其余方面与会话级的临时表相同,再也不列出。
准确的说with语句不叫临时表,但它与临时表使用概念上很是接近,一样列出。
【语法】
【特色】
附着于一个SQL 语句,也只对一个SQL语句产生做用。
能够同时生成几张临时表。
生存期极短,易于管理。
【适用场合】
Global Temporary 的适用场合都适用,只是针对一个SQL的场合
特别方便融入常量或集合运算结果,有简化SQL的做用。
【清除时点】
查询完成后当即清除(数据及表结构)。
例子:
WITH sum_sales AS ( select /*+ materialize */ sum(quantity) all_sales from stores ), number_stores AS ( select /*+ materialize */ count(*) nbr_stores from stores ), sales_by_store AS ( select /*+ materialize */ store_name, sum(quantity) store_sales from store natural join sales ) SELECT store_name FROM store, sum_sales, number_stores, sales_by_store where store_sales > (all_sales / nbr_stores)
(注:使用/*+ materialize */让Oracle基于cost-based(基于成本)的优化策略生成临时表。 )