Oracle用子查询创建临时表的问题总结

本文深入解析Oracle中会话级和事务级临时表的创建与使用方法,包括如何通过子查询填充临时表,以及如何在会话结束或事务提交后保留或删除数据。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

当需要创建临时表来暂时存储一个表的数据时,可以用子查询来实现,语法很简单:

SQL> create global temporary table temp1  as select * from table1;

通过查询临时表temp1,发现只是创建了永久表的一个结构,而并没有将数据复制进去。

我改用永久表来试验子查询的功能,语句如下:

SQL> create table test as select * from table1;

永久表数据复制了,但是临时表没有数据。

原因是Oracle中临时表有两种:
会话级临时表和事务级临时表

1 会话级临时表
  • 创建会话临时表
SQL> create global temporary table tmp_1 (user_id int, user_name varchar2(20)) on commit preserve rows;
# on commit preserve rows表示 当事务提交时 保留数据
  • 向临时表中插入数据
SQL> insert into table tmp_1(user_id,user_name) values(1,'张三');
SQL> insert into table tmp_1(user_id,user_name) values(2,'王二');
SQL> commit;
  • 查询
SQL> select * from tmp_1;

现在表tmp_1是有数据的。

  • 重新打开 一个sql窗口 再次查询 则无数据了

说明此插入的数据,只为本窗口会话存在

2 事务级临时表

  • 创建事务临时表
SQL> create global temporary table tmp_2 (user_id int,user_name varchar2(20)) on commit delete rows;
# on commit delete rows表示 当事务提交时 删除数据 
  • 向临时表中插入数据
SQL> insert into tmp_2(user_id,user_name) values(1,'张三');
SQL> insert into tmp_2(user_id,user_name) values(2,'王二');
  • 查询
SQL> select * from tmp_2;

现在表tmp_2是有数据的。

  • 提交下语句,或者回滚事务,再次查询就没有数据了。
    因为事务临时表,就是在事务提交时,(commit;
    rollback;)就数据清空了。

–查看临时表的表空间,其实他们的表空间为空

 SQL> select table_name, tablespace_name    
 from user_tables 
   where table_name ='TMP_1'   
         or table_name = 'TMP_2';

3 小结

  • on commit delete row
    默认选项,在commit的时候将数据删除
  • on commit preserve row
    在commit的时候将数据保留,会话结束后自动删除。

在语法上,会话临时表采用on commit preserve rows,而事物临时表采用on commit delete rows;在用途上,会话级临时表只会在会话结束时,临时表中的数据才会被截断。而事物临时表则不管是在事物提交(commit)、事物回滚(rollback)或会话结束,临时表中的数据都会被截断。

由于第一种是默认值,我的命令里面没加选项默认为commit后删除数据。所以在我使用Select查询的时候,发现临时表里没有数据。究其原因我们可以归纳为Create table是DDL语句,在触发后,Oracle会隐式的提交给事务处理,因此刚刚插入临时表的数据就被自动删除了。我们把之前的SQL语句改成如下:

SQL> create global temporary table temp2  on commit preserve rows as select * from table1;

再用Select查询temp2,我们如愿的查到了数据。
但是问题又来了,通过这种方式创建的表,数据复制成功,但是会话结束后,不能删除它,怎么样才能在创建之后又可以马上删除呢?我们在Drop table前先 truncate table table_name。语法如下:

SQL> truncate table temp2;
SQL> drop table temp2;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值