`
cancer_sun
  • 浏览: 32158 次
  • 性别: Icon_minigender_1
社区版块
存档分类
最新评论

Oracle临时表GLOBAL TEMPORARY TABLE

 
阅读更多
临时表:像普通表一样,有结构,但是对数据的管理上不一样,临时表存储事务或会话的中间结果集,临时表中保存的数据只对当前会话可见,所有会话都看不到其他会话的数据,即使其他会话提交了,也看不到。临时表不存在并发行为,因为他们对于当前会话都是独立的。
创建临时表时,Oracle只创建了表的结构(在数据字典中定义),并没有初始化内存空间,当某一会话使用临时表时,ORALCE会从当前用户的 临时表空间分配一块内存空间。也就是说只有向临时表中插入数据时,才会给临时表分配存储空间。

临时表分事务级临时表和会话级临时表。 
事务级临时表只对当前事务有效,通过语句:ON COMMIT DELETE ROWS 指定。 
会话级临时表对当前会话有效,通过语句:ON COMMIT PRESERVE ROWS语句指定。 

用法举例(在SCOTT模式下): 
CREATE GLOBAL TEMPORARY TABLE session_temp_tab ON COMMIT PRESERVE ROWS AS SELECT * FROM emp WHERE 1=2;
 ON COMMIT PRESERVE ROWS语句指定所创建的临时表是会话级临时表,当我们断开连接或手动执行DELETE或TRUNCATE之前,临时表中的数据一直存
 在,并且只有当前会话可以看到,其他会话看不到。 

 CREATE GLOBAL TEMPORARY TABLE transaction_temp_tab ON COMMIT DELETE ROWS AS SELECT * FROM emp WHERE 1=2;
 ON COMMIT DELETE ROWS语句指定所创建的临时表是事务级临时表,当COMMIT或ROLLBACK之前,这些数据一直存在,当事务提交之后,表中数据自动清除。

insert into session_temp_tab select * from emp ; 
insert into transaction_temp_tab select * from emp ;


 SQL> select count(*) from session_temp_tab ; 

 COUNT(*) 
---------- 
        14 

 SQL> select count(*) from transaction_temp_tab ; 

 COUNT(*) 
---------- 
        14 
SQL> commit; 

 Commit complete 

 SQL> select count(*) from session_temp_tab ; 

 COUNT(*) 
---------- 
        14 

 SQL> select count(*) from transaction_temp_tab ; 

 COUNT(*) 
---------- 
        0 


当COMMIT之后事务级临时表中的数据自动清除,所以再次查询的时候得到结果为0; 
SQL> disconnect ; 
Not logged on 

 SQL> connect scott/tiger ; 
Connected to Oracle Database 11g Enterprise Edition Release 11.1.0.6.0 
Connected as scott 

 SQL> select count(*) from transaction_temp_tab ; 

 COUNT(*) 
---------- 
        0 

 SQL> select count(*) from session_temp_tab ; 

 COUNT(*) 
---------- 
        0 
当断开之后重新连接之后,会话级临时表中的数据也被自动删除了。
===============================================================================
5.tempporary 
也是heap表的一种,有两种临时表。
SQL> create global temporary table gt1 as select * from dba_objects;

Table created.

SQL> select * from gt1;--没有数据,因为省掉了on commit delete rows

no rows selected
SQL> create global temporary table gt2 on commit delete rows as select * from dba_objects;

Table created.

--还有一种临时表,在提交的时候保留数据
SQL> create global temporary table gt3 on commit preserve rows as select * from dba_objects;

Table created.

SQL> select count(1) from gt3;

  COUNT(1)
----------
     10042
--另一个CMD
SQL> select count(1) from gt3;

  COUNT(1)
----------
         0
这个表是实实在在的表,这个表结构任何一个SESSION都能看到。但是每个SESSION的数据都是隔离的。定义保留在数据字典,数据保存在临时表空间里。
使用它减少对日志的产生。
10g,创建这个表属于哪个用户,就缺省的放在这个用户缺省的临时表空间里。11g可以单独放在一个表空间里。
===============================================================================
在Oracle8i或以上版本中,可以创建以下两种临时表:
1。会话特有的临时表
CREATE GLOBAL TEMPORARY <TABLE_NAME> (<column specification>)
ON COMMIT PRESERVE ROWS;

2。事务特有的临时表
CREATE GLOBAL TEMPORARY <TABLE_NAME> (<column specification>)
ON COMMIT DELETE ROWS;
CREATE GLOBAL TEMPORARY TABLE MyTempTable
所建的临时表虽然是存在的,但是你试一下insert 一条记录然后用别的连接登上去select,记录是空的,明白了吧,我把下面两句话再贴一下:
--ON COMMIT DELETE ROWS 说明临时表是事务指定,每次提交后ORACLE将截断表(删除全部行)
--ON COMMIT PRESERVE ROWS 说明临时表是会话指定,当中断会话时ORACLE将截断表。
冲突的问题更本不用考虑.

临时表只是保存当前会话(session)用到的数据,数据只在事务或会话期间存在。

通过CREATE GLOBAL TEMPORARY TABLE命令创建一个临时表,对于事务类型的临时表,
数据只是在事务期间存在,对于会话类型的临时表,数据在会话期间存在。

会话的数据对于当前会话私有。每个会话只能看到并修改自己的数据。DML锁不会加到
临时表的数据上。下面的语句控制行的存在性。

● ON COMMIT DELETE ROWS 表名行只是在事务期间可见
● ON COMMIT PRESERVE ROWS 表名行在整个会话期间可见

可以对临时表创建索引,视图,出发器,可以用export和import工具导入导出表的
定义,但是不能导出数据。表的定义对所有的会话可见。

Temporary Tables临时表
1简介
   ORACLE数据库除了可以保存永久表外,还可以建立临时表temporary tables。这些临时表用来保存一个会话SESSION的数据,
   或者保存在一个事务中需要的数据。当会话退出或者用户提交commit和回滚rollback事务的时候,临时表的数据自动清空,
   但是临时表的结构以及元数据还存储在用户的数据字典中。
   临时表只在oracle8i以及以上产品中支持。
2详细介绍
   Oracle临时表分为 会话级临时表 和 事务级临时表。
会话级临时表是指临时表中的数据只在会话生命周期之中存在,当用户退出会话结束的时候,Oracle自动清除临时表中数据。
事务级临时表是指临时表中的数据只在事务生命周期中存在。当一个事务结束(commit or rollback),Oracle自动清除临时表中数据。
临时表中的数据只对当前Session有效,每个Session都有自己的临时数据,并且不能访问其它Session的临时表中的数据。因此,
临时表不需要DML锁.当一个会话结束(用户正常退出 用户不正常退出 ORACLE实例崩溃)或者一个事务结束的时候,Oracle对这个会话的
表执行 TRUNCATE 语句清空临时表数据.但不会清空其它会话临时表中的数据.
你可以索引临时表和在临时表基础上建立视图.同样,建立在临时表上的索引也是临时的,也是只对当前会话或者事务有效. 
临时表可以拥有触发器.
3建立临时表
   临时表的定义对所有会话SESSION都是可见的,但是表中的数据只对当前的会话或者事务有效.
   建立方法:
1) ON COMMIT DELETE ROWS 定义了建立事务级临时表的方法.
CREATE GLOBAL TEMPORARY TABLE admin_work_area
(startdate DATE,
enddate DATE,
class CHAR(20))
ON COMMIT DELETE ROWS;
EXAMPLE:
SQL> CREATE GLOBAL TEMPORARY TABLE admin_work_area
  2  (startdate DATE,
  3  enddate DATE,
  4  class CHAR(20))
  5  ON COMMIT DELETE ROWS;
SQL> create table permernate( a number);
SQL> insert into admin_work_area values(sysdate,sysdate,'temperary table');
SQL> insert into permernate values(1);
SQL> commit;
SQL> select * from admin_work_area;
SQL> select  * from permernate;
A
1
2)ON COMMIT PRESERVE ROWS 定义了创建会话级临时表的方法.
CREATE GLOBAL TEMPORARY TABLE admin_work_area
(startdate DATE,
enddate DATE,
class CHAR(20))
ON COMMIT PRESERVE ROWS;
EXAMPLE:
会话1:
SQL> drop table admin_work_area;
SQL> CREATE GLOBAL TEMPORARY TABLE admin_work_area
  2  (startdate DATE,
  3  enddate DATE,
  4  class CHAR(20))
  5  ON COMMIT PRESERVE ROWS;
SQL> insert into permernate values(2);
SQL> insert into admin_work_area values(sysdate,sysdate,'session temperary');
SQL> commit;
SQL> select * from permernate;
         A
----------
         1
         2
SQL> select * from admin_work_area;
STARTDATE  ENDDATE    CLASS
---------- ---------- --------------------
17-1?? -03 17-1?? -03 session temperary
会话2:
SQL> select * from permernate;
         A
----------
         1
         2
SQL> select * from admin_work_area;
未选择行.
会话2看不见会话1中临时表的数据.

4 ORACLE临时表和SQLSERVER临时表异同
SQLSERVER临时表
也可以创建临时表。临时表与永久表相似,但临时表存储在 tempdb 中,当不再使用时会自动删除。
有本地和全局两种类型的临时表,二者在名称、可见性和可用性上均不相同。本地临时表的名称以单个数字符号 (#) 打头;
它们仅对当前的用户连接是可见的;当用户从 Microsoft? SQL Server? 2000 实例断开连接时被删除。全局临时表的名称以数学符号
(##) 打头,创建后对任何用户都是可见的,当所有引用该表的用户从 SQL Server 断开连接时被删除。
例如,如果创建名为 employees 的表,则任何人只要在数据库中有使用该表的安全权限就可以使用该表,除非它已删除。
如果创建名为 #employees 的本地临时表,只有您能对该表执行操作且在断开连接时该表删除。如果创建名为 ##employees 的全局临时表
,数据表中的任何用户均可对该表执行操作。如果该表在您创建后没有其他用户使用,则当您断开连接时该表删除。如果该表在您创建
后有其他用户使用,则 SQL Server在所有用户断开连接后删除该表
不同:
1.SQL SERVER临时表是一种”内存表”,表是存储在内存中的.ORACLE临时表除非执行DROP TABLE,否则表定义会保留在数据字典中.
2.SQL SERVER临时表不存在类似ORACLE临时表 事务级别 上的功能.
3.SQL SERVER本地临时表(#) 与 ORACLE的会话级别临时表类似,但是在会话退出的时候,ORACLE不会删除表.
4.SQL SERVER的全局临时表(##) 是指多个连接共享同一片内存.当没有指针引用该内存区域时,SQL SERVER自动释放全局临时表.
5.由于ORACLE不是一种 内存中的数据库. 所以如果ORACLE类似SQL SERVER 频繁的对临时表进行建立和删除,必定会影响性能.
所以ORACLE会保留临时表的定义直到用户DROP TABLE.
6.在ORACLE中,如果需要多个用户共享一个表(类似SQL SERVER的全局临时表##).则可以利用永久表,
并且在表中添加一些可以唯一标识用户的列.利用触发器和视图.当用户退出的时候,根据该登陆用户的唯一信息删除相应的表中的数据.
这种方法给ORACLE带来了一定量的负载.

===============================================================================
SQL的IN中有很多值,如何处理能提高效率?            

近日碰到一个棘手的问题,从外部得到了一组ID数据,要跟Oracle中的某个表做比对,从Oracle中取出ID一样的数据。举个例子,pub有版主有会员,版主是会员的子集,版主名单存在Oracle里面,但会员名单没存在里面。假设pub在搞抽奖活动,一小时一次,中奖的会员名单通过中奖系统传给Oracle。我现在想把刚才中奖的会员中是版主的名单列出来,该怎么做。
实际环境中,通过外部获得的数据数量级为K,Oracle的这个表数量级为几十K到上百K,比对效率成为一个关键因素。我能想到的方法就是构造多条SQL语句,把这些ID作为IN的列表值传进去(IN后的列表项不能超过1000个,故可能会需要多个sql)。
带着问题咨询了yangtingkun ,得到的答复是效率不会太高也不会太低,Oracle可能会做全表扫描,但效率比你一个一个去比对肯定要快了。实际执行了一下,IN里面传了300个参数,得到执行计划如下(做的是 INDEX RANGE SCAN):
执行计划
----------------------------------------------------------
Plan hash value: 1656459801
-----------------------------------------------------------------------------
| Id  | Operation         | Name    | Rows  | Bytes | Cost (%CPU)| Time     |
-----------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |         |   284 |  1136 |     1   (0)| 00:00:01 |
|   1 |  INLIST ITERATOR  |         |       |       |            |          |
|*  2 |   INDEX RANGE SCAN| XXXXXX|   284 |  1136 |     1   (0)| 00:00:01 |
-----------------------------------------------------------------------------
拼多个sql语句是麻烦一点,不过这样做效率上没啥问题。想想也是,总比我将数据插入表,通过表关联去做要方便一些,因为建表的话我毕竟还需要对表里的数据进行维护。
“哦,这样的话,你建一个临时表吧!”
“global temporary table?”
“嗯,这表就是专门用来解决这样的问题的!临时数据只管往里面插,可通过on submit关键字设置为会话有效或者事务有效,各会话间互相看不到数据,不会互相影响。”
哈哈,原来问题这么简单啊!省去了数据维护的麻烦,得到了表关联带来的高效数据处理,唯一会影响到效率的问题就是往临时表里插数据了,一条一条显然很慢了,考虑用存储过程来实现,呵呵。

插入多行数据,使用union
DB.ExcuteNonQuery("Delete from t863_Y_UKIDS_XL");
sSqlInsertTemp = "INSERT INTO  t863_Y_UKIDS_XL(iukid) " + sXLsqlvalue;

INSERT INTO  t863_Y_UKIDS(iukid)
SELECT  123   FROM  DUAL
 UNION SELECT  456   FROM  DUAL
 UNION SELECT  1233   FROM  DUAL
 UNION SELECT  4526   FROM  DUAL
 UNION SELECT  12333   FROM  DUAL
 UNION SELECT  456   FROM  DUAL
<script type="text/javascript"> $(function () { $('pre.prettyprint code').each(function () { var lines = $(this).text().split('\n').length; var $numbering = $('<ul/>').addClass('pre-numbering').hide(); $(this).addClass('has-numbering').parent().append($numbering); for (i = 1; i <= lines; i++) { $numbering.append($('<li/>').text(i)); }; $numbering.fadeIn(1700); }); }); </script>
分享到:
评论

相关推荐

    Oracle存储过程中使用临时表

    Oracle存储过程中使用临时表 会话级临时表 事务级临时表

    oracle 临时表详解及实例

    在Oracle8i或以上版本中,可以创建以下两种临时表: 1。会话特有的临时表 CREATE GLOBAL TEMPORARY &lt;TABLE&gt; ( &lt;column&gt; ) ON COMMIT PRESERVE ROWS;  2。事务特有的临时表 CREATE GLOBAL TEMPORARY &lt;TABLE&gt; ( ...

    MySQL中的两种临时表

     通过CREATE TEMPORARY TABLE 创建的临时表,这种临时表称为外部临时表。这种临时表只对当前用户可见,当前会话结束的时候,该临时表会自动关闭。这种临时表的命名与非临时表可以同名(同名后非临时表将对当前会话...

    对比Oracle临时表和SQL Server临时表的不同点

    Oracle数据库除了可以保存永久表外,还可以建立临时表temporary tables。这些临时表用来保存一个会话SESSION的数据,或者保存在一个事务中需要的数据。当会话退出或者用户提交commit和回滚rollback事务的时候,临时...

    Oracle_临时表介绍

    目前所有使用Oracle作为数据库支撑平台的应用,大部分数据量比较庞大的系统,即表的数据量一般情况下都是在百万级以上的数据量。当然在Oracle中创建分区是一种不错的选择...那么这个时候我考虑在Oracle中创建“临时表”

    MYSQL 临时表用法总结

    MYSQL 临时表用法总结 1.背景 老项目最近被吐槽性能不行,经排查发现mysql占用cpu...如果在你创建名为test_table_20200313临时表时名为test_table_20200313的表在数据库中已经存在,临时表将隐藏非临时表test_table_202

    longxuegang#MySQL5.7#241-临时表优化1

    1.背景MySQL包括两类临时表,一类是通过create temporary table创建的临时表,一类是在query过程中using temporary而创

    36.为什么临时表可以重名?1

    1. 建表语法是create temporary table … 2. 一个临时表只能被创建它的session访问,对其他线程不可见 3. 临时表可以与普通表同

    oracle客户端连接服务器常见问题

    有实践过的,解决方法都是真的,oracle客户端连接服务器常见问题

    Mysql临时表及分区表区别详解

    临时表与内存表 内存表,指的是使用Memory引擎的表,建表语法是create table … engine=memory。这种 表的数据都保存在内存里,系统重启的时候会被清空,但是表结构还在。除了这两个特性看 上去比较“奇怪”外,从...

    MySQL两种临时表的用法详解

    通过CREATE TEMPORARY TABLE 创建的临时表,这种临时表称为外部临时表。这种临时表只对当前用户可见,当前会话结束的时候,该临时表会自动关闭。这种临时表的命名与非临时表可以同名(同名后非临时表将对当前会话不...

    创建Oracle表空间

    /*第1步:创建临时表空间 */ create temporary tablespace user_temp tempfile 'D:\oracle\oradata\Oracle9i\user_temp.dbf' size 50m autoextend on next 50m maxsize 20480m extent management local; ...

    MySQL临时表的简单用法介绍

    创建临时表很容易,给正常的CREATE TABLE语句加上TEMPORARY关键字: CREATE TEMPORARY TABLE tmp_table ( name VARCHAR(10) NOT NULL, value INTEGER NOT NULL ) 临时表将在你连接MySQL期间存在。当你断开时,...

    深度解析MySQL 5.7之临时表空间

    在MySQL里的临时表指的就是以create temporary table 这样的关键词创建的表。 3、事务级别临时表 这种临时表在事务开始时生效,事务提交或者回滚后失效。 在MySQL里面没有这种临时表,必须利用会话级别的临时表

    ORACLE 存储过程返回结果集,拼接为字符串输出为clob

    CLOB变量需要dbms_lob.createtemporary,临时表空间中,建立临时LOB。 大数据量,返回值虽然是CLOB,依然会报错; CLOB变量需要dbms_lob.createtemporary,临时表空间中,建立临时LOB。 大数据量,返回值虽然是CLOB...

    pgtt:PostgreSQL扩展,用于创建,管理和使用Oracle风格的全局临时表以及其他RDBMS

    pgtt是PostgreSQL扩展,用于创建,管理和使用Oracle风格的Global Temporary Tables和其他RDBMS。 此扩展的目的是提出一个扩展,以提供等待核心实现的全局临时表功能。 此扩展的主要目的是在迁移到PostgreSQL时无法...

    解析Mysql临时表及特点

    临时表是当连接没有断开时存在,一旦断开就不会存在,临时表的数据和结构都在内存中,可以做个测验,你创建一个临时表,但是到响应的数据目录下并不会找到.frm文件mysql&gt; CREATE TEMPORARY TABLE tmp_table ( -&gt; -...

    Oracle常用的命令如何查看表的结构

    10 temporary tablespace temp --临时表空间为temp 11 profile default --受profile文件的限制 12 quota unlimited on 表空间名; --在表空间下面建表不受限制 4.创建角色 create role 角色名 identified by 密码;...

    Mysql临时表原理及创建方法解析

    mysql 利用 temporary 关键字就可以创建出一个临时表。创建的这张表会在与服务器的会话终止时自动消失 语法:create temporary table tbl_name…; 规则:每个会话只能看到自己创建的临时表,不同的会话可以创建相同...

Global site tag (gtag.js) - Google Analytics