SQL临时表的使用

临时表在Sqlserver数据库中,是非常重要的,下面就详细介绍SQL数据库中临时表的特点及其使用,仅供参考。

 

临时表与永久表相似,但临时表存储在tempdb中,当不再使用时会自动删除。临时表有两种类型:本地和全局。它们在名称、可见性以及可用性上有区别。

对于临时表有如下几个特点:

本地临时表就是用户在创建表的时候添加了“#”前缀的表,其特点是根据数据库连接独立。只有创建本地临时表的数据库连接有表的访问权限,其它连接不能访问该表;
不同的数据库连接中,创建的本地临时表虽然“名字”相同,但是这些表之间相互并不存在任何关系;在SQLSERVER中,通过特别的命名机制保证本地临时表在数据库连接上的独立性。
真正的临时表利用了数据库临时表空间,由数据库系统自动进行维护,因此节省了表空间。并且由于临时表空间一般利用虚拟内存,大大减少了硬盘的I/O次数,因此也提高了系统效率。
临时表在事务完毕或会话完毕数据自动清空,不必记得用完后删除数据。
 

本地临时表

本地临时表的名称以单个数字符号 (#) 打头;它们仅对当前的用户连接(也就是创建本地临时表的connection)是可见的;当用户从 SQL Server 实例断开连接时被删除。

 

例如我们在一个数据库连接中用如下语句创建本地临时表#Temp

数据库连接1:


CREATE TABLE #Temp
(
    id int,
    customer_name nvarchar(50),
    age int
)

然后同时启动数据库连接2,执行查询#Temp的操作
数据库连接2:

select * from #Temp
我们来看看数据库连接2的结果是什么?
数据库连接2:

 

结果显示,数据库连接2找不到表#Temp。这说明#Temp这张临时表,只是对创建它的数据库连接1可见,而对于数据库连接2来说是不可见的。

 

 

全局临时表

全局临时表的名称以两个数字符号 (##) 打头,创建后对任何数据库连接都是可见的,当所有引用该表的数据库连接从 SQL Server 断开时被删除。

例如我们在一个数据库连接中用如下语句创建全局临时表##Temp,然后插入三行数据

数据库连接1:


CREATE TABLE ##Temp
(
    id int,
    customer_name nvarchar(50),
    age int
)

INSERT INTO ##Temp VALUES(1,'老王',20),(2,'老张',30),(3,'老李',25)

接着我们在数据库连接2中,查询##Temp的数据
数据库连接2:

select * from ##Temp
数据库连接2结果如下
数据库连接2:

可以看到,数据库连接2可以成功访问到数据库连接1创建的全局临时表##Temp,但是如果我们现在关闭数据连接1,然后再执行数据库连接2的##Temp查询语句会发生什么呢?结果如下:

关闭数据库连接1,然后数据库连接2再次执行:

select * from ##Temp


我们发现关闭数据库连接1后,数据库连接2就找不到全局临时表##Temp了。这是因为数据库连接1被关闭后,数据库连接2此时也没有语句正在使用临时表##Temp,所以Sqlserver认为此时已经没有数据库连接在引用全局临时表##Temp了,就将##Temp释放掉了。

 

接下来,我们尝试在数据库连接2中对全局临时表##Temp持有事务中的排他锁(X锁)后,然后关闭数据库连接1.

数据库连接1:


CREATE TABLE ##Temp
(
    id int,
    customer_name nvarchar(50),
    age int
)

INSERT INTO ##Temp VALUES(1,'老王',20),(2,'老张',30),(3,'老李',25)

数据库连接2:

BEGIN TRAN
select * from ##Temp with(xlock)
关闭数据库连接1,然后数据库连接2执行:

select * from ##Temp


结果显示我们尽管关闭了数据库连接1,但是由于数据库连接2在事务中一直持有全局临时表##Temp的排他锁(X锁),所以临时表##Temp并没有随着数据库连接1的关闭而被释放掉,只要数据库连接2中启动的事务没有被回滚或提交,那么数据库连接2会一直持有临时表##Temp的排他锁,这时Sqlserver会认为还有数据库连接正在引用全局临时表##Temp,所以##Temp不会被释放掉。

查询数据并写入临时表:

select * into #tab from table;

删除临时表:

 

<think>我们被要求回答关于Oracle SQL临时表使用方法。根据引用内容,Oracle中有全局临时表(GLOBAL TEMPORARY TABLE)和私有临时表(PRIVATE TEMPORARY TABLE,12c引入)两种。此外,引用[2]还提到了临时表空间的使用情况查询,引用[3]展示了全局临时表的一个例子和undo使用情况。 在Oracle中,临时表用于存储会话或事务中的临时数据,数据在会话结束或事务结束时自动清除。全局临时表的结构是持久的,但数据是临时的。私有临时表(12c及以上)的表结构和数据都是临时的,并在会话结束时自动删除。 下面分别介绍两种临时表使用方法: 1. 全局临时表(GLOBAL TEMPORARY TABLE): - 创建表时使用`GLOBAL TEMPORARY`关键字。 - 可以指定数据是事务级(ON COMMIT DELETE ROWS)还是会话级(ON COMMIT PRESERVE ROWS)的。 - 事务级:每次提交事务后,数据自动清空。 - 会话级:数据在整个会话期间都存在,直到会话结束或手动删除。 示例: ```sql -- 创建事务级的全局临时表 CREATE GLOBAL TEMPORARY TABLE gtt_transaction ( id NUMBER, name VARCHAR2(50) ) ON COMMIT DELETE ROWS; -- 创建会话级的全局临时表 CREATE GLOBAL TEMPORARY TABLE gtt_session ( id NUMBER, name VARCHAR2(50) ) ON COMMIT PRESERVE ROWS; ``` 2. 私有临时表(PRIVATE TEMPORARY TABLE,12c及以上版本): - 表名必须以`ORA$PTT_`为前缀(可以修改,但通常使用默认前缀)。 - 使用`ON COMMIT`定义数据保留策略,同时表是会话私有的,在会话结束时自动删除(包括结构和数据)。 - 创建语法中使用`PRIVATE TEMPORARY`关键字。 示例: ```sql -- 创建事务级的私有临时表(提交后数据删除,会话结束表自动删除) CREATE PRIVATE TEMPORARY TABLE ora$ptt_temp ( id NUMBER, name VARCHAR2(50) ) ON COMMIT DROP DEFINITION; -- 注意:ON COMMIT DROP DEFINITION 表示提交时删除表(包括结构和数据),但Oracle也支持ON COMMIT PRESERVE DEFINITION(提交时保留表结构,只删除数据) -- 或者使用ON COMMIT PRESERVE DEFINITION(提交后保留表定义,只删除数据,会话结束表自动删除) CREATE PRIVATE TEMPORARY TABLE ora$ptt_temp_session ( id NUMBER, name VARCHAR2(50) ) ON COMMIT PRESERVE DEFINITION; ``` 注意:私有临时表在12.2及以上版本中引入,并且表名必须以前缀开头(默认是ORA$PTT_,但可以通过参数修改)。 使用临时表时,需要注意: - 临时表不产生redo日志,但是会产生undo日志(用于回滚),如引用[3]所示。 - 临时表的数据不会备份,也不会被恢复。 - 临时表可以创建索引、约束等,但同样也是临时的。 另外,引用[2]提供了查询临时表空间使用情况的SQL,这对于监控临时表空间的使用很有帮助。 下面给出一个使用全局临时表的完整示例: ```sql -- 创建全局临时表(会话级) CREATE GLOBAL TEMPORARY TABLE my_gtt ( id NUMBER, data VARCHAR2(100) ) ON COMMIT PRESERVE ROWS; -- 插入数据 INSERT INTO my_gtt VALUES (1, 'Session data'); -- 提交后数据仍然存在(因为是会话级) COMMIT; -- 查询数据 SELECT * FROM my_gtt; -- 结束会话后,数据自动清除。 -- 删除全局临时表(如果需要) DROP TABLE my_gtt; ``` 私有临时表使用示例: ```sql -- 创建私有临时表(事务级:提交时删除表) CREATE PRIVATE TEMPORARY TABLE ora$ptt_my_temp ( id NUMBER, data VARCHAR2(100) ) ON COMMIT DROP DEFINITION; -- 插入数据 INSERT INTO ora$ptt_my_temp VALUES (1, 'Temporary data'); -- 查询 SELECT * FROM ora$ptt_my_temp; -- 提交后,表自动被删除,无法再查询。 COMMIT; -- 注意:在提交之前,可以像普通表一样使用。 ``` 总结: - 全局临时表:表结构持久,数据临时(根据定义在事务结束或会话结束时清除)。 - 私有临时表:表结构和数据都是临时的,在会话结束或事务提交时(根据定义)自动删除。 根据需求选择合适的临时表类型。 相关问题: 1. 全局临时表和私有临时表的主要区别是什么? 2. 如何监控Oracle临时表空间的使用情况? 3. 临时表在什么情况下会产生重做日志和撤销日志? 4. 在Oracle中,临时表是否支持并行操作?</think>### Oracle SQL 临时表使用方法详解 在Oracle中,临时表主要用于存储会话或事务中的临时数据,分为两种类型:**全局临时表(GLOBAL TEMPORARY TABLE)** 和 **私有临时表(PRIVATE TEMPORARY TABLE)**(12c及以上版本支持)。以下是具体使用方法: --- #### 一、全局临时表(GLOBAL TEMPORARY TABLE) **特点**:表结构持久化存储,数据根据配置在事务或会话结束时自动清除。 1. **创建语法** ```sql CREATE GLOBAL TEMPORARY TABLE 表名 ( 列1 数据类型, 列2 数据类型 ) ON COMMIT [DELETE ROWS | PRESERVE ROWS]; ``` - **`ON COMMIT DELETE ROWS`**:事务级临时表(提交后数据自动清除)[^1][^3] ```sql CREATE GLOBAL TEMPORARY TABLE gtt_transaction ( id INT, name VARCHAR2(50) ) ON COMMIT DELETE ROWS; ``` - **`ON COMMIT PRESERVE ROWS`**:会话级临时表(会话结束前数据保留) ```sql CREATE GLOBAL TEMPORARY TABLE gtt_session ( id INT, value VARCHAR2(10) ) ON COMMIT PRESERVE ROWS; ``` 2. **数据操作** 插入/查询数据与普通表相同,但数据仅对当前会话可见: ```sql INSERT INTO gtt_transaction VALUES (1, '测试'); SELECT * FROM gtt_transaction; -- 仅当前会话可见 ``` 3. **注意事项** - 表结构需提前创建,数据自动清理无需手动干预。 - 不产生重做日志(Redo),但会生成撤销日志(Undo)用于事务回滚[^3]。 --- #### 二、私有临时表(PRIVATE TEMPORARY TABLE, 12c+) **特点**:表结构和数据均为临时,会话结束时自动删除。 1. **创建语法** ```sql CREATE PRIVATE TEMPORARY TABLE 表名 ( 列1 数据类型, 列2 数据类型 ) ON COMMIT [DROP DEFINITION | PRESERVE DEFINITION]; ``` - **`ON COMMIT DROP DEFINITION`**:事务级(提交后表结构和数据均删除) ```sql CREATE PRIVATE TEMPORARY TABLE ora$ptt_temp ( id INT, data VARCHAR2(100) ) ON COMMIT DROP DEFINITION; ``` - **`ON COMMIT PRESERVE DEFINITION`**:会话级(会话结束前保留表结构) ```sql CREATE PRIVATE TEMPORARY TABLE ora$ptt_temp_session ( id INT, value VARCHAR2(20) ) ON COMMIT PRESERVE DEFINITION; ``` 2. **命名规则** 表名必须以 `ORA$PTT_` 开头(默认前缀,可通过参数修改)。 --- #### 三、临时表空间监控 使用以下SQL监控临时表空间使用情况[^2]: ```sql SELECT f.tablespace_name, ROUND(f.sum_space, 2) "总空间(MB)", ROUND(u.used_space, 2) "已用空间(MB)", ROUND(f.sum_space - u.used_space, 2) "空闲空间(MB)", ROUND(u.used_space / f.sum_space * 100, 2) "使用率(%)" FROM ( SELECT tablespace_name, SUM(bytes)/1024/1024 AS sum_space FROM sys.dba_temp_files GROUP BY tablespace_name ) f JOIN ( SELECT tablespace, SUM(blocks * 8)/1024 AS used_space FROM sys.v_$sort_usage GROUP BY tablespace ) u ON f.tablespace_name = u.tablespace; ``` --- #### 四、典型应用场景 1. 中间结果存储(如复杂查询的分步计算)。 2. 批量数据处理时暂存中间状态。 3. 避免事务锁竞争(临时表数据对其他会话不可见)。 --- **注意事项**: - 全局临时表需显式创建(DDL操作),私有临时表自动销毁。 - 临时表不支持分区。 - 索引可在临时表上创建,但同样为临时对象。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值