Sql Server临时表

本文介绍了SQL Server中的临时表,包括本地和全局临时表的区别与使用方式。本地临时表仅限于当前会话,而全局临时表则可在所有会话中访问。文章详细说明了如何创建这些表,以及它们在不同场景下的生命周期。

临时表
可以创建本地和全局临时表。本地临时表仅在当前会话中可见;全局临时表在所有会话中都可见。可参见官方文档

https://docs.microsoft.com/zh-cn/sql/relational-databases/databases/tempdb-database?view=sql-server-ver15  tempdb介绍

https://docs.microsoft.com/zh-cn/sql/relational-databases/tables/tables?view=sql-server-ver15 关于表类型

本地临时表的名称前面有一个编号符 (#table_name),而全局临时表的名称前面有两个编号符 (##table_name)。

SQL 语句使用 CREATE TABLE 语句中为 table_name 指定的名称引用临时表:

CREATE TABLE #MyTempTable (cola INT PRIMARY KEY)
INSERT INTO #MyTempTable VALUES (1)

如果本地临时表由存储过程创建或由多个用户同时执行的应用程序创建,则 SQL Server 必须能够区分由不同用户创建的表。为此,SQL Server 在内部为每个本地临时表的表名追加一个数字后缀。存储在 tempdb 数据库的 sysobjects 表中的临时表,其全名由 CREATE TABLE 语句中指定的表名和系统生成的数字后缀组成。为了允许追加后缀,为本地临时表指定的表名 table_name 不能超过 116 个字符。

除非使用 DROP TABLE 语句显式除去临时表,否则临时表将在退出其作用域时由系统自动除去: 

当存储过程完成时,将自动除去在存储过程中创建的本地临时表。由创建表的存储过程执行的所有嵌套存储过程都可以引用此表。但调用创建此表的存储过程的进程无法引用此表。


所有其它本地临时表在当前会话结束时自动除去。


全局临时表在创建此表的会话结束且其它任务停止对其引用时自动除去。任务与表之间的关联只在单个 Transact-SQL 语句的生存周期内保持。换言之,当创建全局临时表的会话结束时,最后一条引用此表的 Transact-SQL 语句完成后,将自动除去此表

<think>我们正在讨论SQL Server中的临时表。根据用户的问题,他想了解SQL Server临时表的相关信息。结合之前提供的引用材料,我将系统地介绍临时表的概念、类型、使用场景、注意事项以及一些优化技巧。 引用内容回顾: [^1] 介绍了临时表是处理临时数据的重要工具,分为本地(#)和全局(##)两种,并提到需注意tempdb资源占用和会话隔离特性。 [^2] 详细说明了临时表的两种类型:本地临时表(仅创建者可见,断开连接后删除)和全局临时表(所有用户可见,当所有引用它的用户都断开连接后删除)。 [^3] 指出当多个用户同时创建同名本地临时表时,SQL Server会追加数字后缀来区分,因此表名不能超过116个字符。 [^4] 再次强调了本地临时表的作用范围和生命周期(仅在创建会话中可访问,会话关闭时自动删除)。 [^5] 展示了临时表与视图联合使用的优化技巧,包括将视图结果存入临时表并创建索引,以及使用动态SQL生成临时表。 基于以上引用,我将组织回答如下: ### 📚 SQL Server临时表详解 #### 一、基本概念 临时表是存储在**tempdb系统数据库**中的特殊表,用于存储临时数据。它们不会长期存在,根据类型在不同条件下自动销毁。临时表分为两类: 1. **本地临时表**(以单个`#`开头) - **作用范围**:仅在创建它的当前会话中可见[^2][^4] - **生命周期**:会话结束时(连接关闭)自动删除[^2] - **命名规则**:实际表名会被追加随机后缀(如`#Sales_00000000001E`)[^3] - **创建示例**: ```sql CREATE TABLE #LocalTemp ( ID INT PRIMARY KEY, ProductName VARCHAR(50) ); ``` 2. **全局临时表**(以两个`##`开头) - **作用范围**:对所有连接可见[^2] - **生命周期**:当所有引用它的会话都断开连接时自动删除[^2] - **创建示例**: ```sql CREATE TABLE ##GlobalTemp ( OrderID INT, CustomerName NVARCHAR(100) ); ``` #### 二、核心特性对比 | 特性 | 本地临时表 | 全局临时表 | |---------------------|--------------------|--------------------| | **可见性** | 仅创建会话 | 所有会话 | | **删除时机** | 会话结束 | 所有会话断开后 | | **命名长度限制** | ≤116字符[^3] | ≤128字符 | | **并发安全性** | 自动后缀避冲突[^3] | 需手动确保唯一性 | #### 三、典型应用场景 1. **中间结果暂存** ```sql -- 将复杂查询结果存入临时表 SELECT * INTO #TempResults FROM Orders WHERE OrderDate > '2023-01-01'; ``` 2. **跨批处理数据共享** ```sql -- 批处理1:创建并填充临时表 CREATE TABLE #UserData (UserID INT); INSERT INTO #UserData VALUES (101), (102); GO -- 批处理2:复用临时表(同一会话内) SELECT * FROM #UserData; ``` 3. **与视图联合优化查询**[^5] ```sql -- 步骤1:创建视图简化基础查询 CREATE VIEW vw_RecentSales AS ...; -- 步骤2:将视图结果导入临时表 SELECT * INTO #TempSales FROM vw_RecentSales; -- 步骤3:在临时表上创建索引加速分析 CREATE INDEX IX_Product ON #TempSales(ProductID); ``` #### 四、使用注意事项 1. **资源管理** - 临时表占用`tempdb`空间,需监控其增长[^1] - 高并发场景避免创建过大临时表 2. **事务控制** ```sql BEGIN TRANSACTION; INSERT INTO #LocalTemp VALUES (1, 'Laptop'); ROLLBACK; -- 回滚后数据仍存在(临时表不受事务影响) ``` 3. **架构绑定限制** - 不能直接在存储过程外为临时表创建视图 - 动态SQL中创建的临时表仅在动态语句内有效 #### 五、性能优化技巧 1. **索引优化** ```sql -- 为大表添加索引 CREATE INDEX IX_Product ON #TempSales(ProductID); ``` 2. **统计信息更新** ```sql UPDATE STATISTICS #TempSales; -- 改善查询优化器决策 ``` 3. **混合使用视图与临时表**[^5] ```sql -- 通过视图预过滤数据 SELECT * INTO #FilteredData FROM vw_HighValueOrders WHERE Amount > 5000; ``` 4. **动态SQL高效建表** ```sql DECLARE @SQL NVARCHAR(MAX) = N' SELECT ProductID, SUM(Quantity) AS TotalQty INTO #DynamicTemp FROM OrderDetails GROUP BY ProductID; '; EXEC sp_executesql @SQL; -- 临时表仅在动态SQL内有效 ``` #### 六、与表变量对比 | 特性 | 临时表 | 表变量 | |--------------------|----------------------|----------------------| | **存储位置** | tempdb磁盘 | 内存(小量)/tempdb | | **索引支持** | 支持完整索引 | 仅主键/唯一约束 | | **统计信息** | 自动更新 | 无统计信息 | | **作用域** | 会话/批处理 | 当前批处理 | | **事务回滚影响** | 数据保留 | 数据回滚 | §§ 相关问题 §§ 1. 临时表在事务回滚时数据会保留吗? 2. 如何监控 tempdb 中临时表的空间占用? 3. 临时表和表变量在性能上如何选择? 4. 全局临时表是否支持跨多个连接的事务? </think>### 📚 SQL Server临时表详解 #### 一、核心概念 1. **定义** - 临时表是存储在 **`tempdb`系统数据库**中的特殊表,用于存储会话级或批处理级的临时数据[^1][^2]。 - 数据生命周期短暂,**自动清理**(会话结束或连接断开时)[^4]。 2. **类型对比** | 类型 | 前缀 | 可见范围 | 删除时机 | |--------------|--------|------------------------|------------------------------| | **本地临时表** | `#` | 仅创建它的当前会话 | 会话结束(连接断开)[^2][^4] | | **全局临时表** | `##` | 所有活动会话 | 所有引用它的会话均断开[^2] | --- #### 二、核心特性与使用场景 1. **自动后缀机制** - 当多个会话创建同名本地临时表时,SQL Server 自动追加**数字后缀**(如 `#Table_00000000001E`),确保唯一性[^3]。 - 命名限制:本地临时表名 ≤ 116字符(因后缀占用空间)[^3]。 2. **典型应用场景** - **复杂查询中间结果存储**: ```sql SELECT * INTO #TempSales FROM Orders WHERE Year = 2023; ``` - **跨批处理数据共享**(同一会话内)[^4]: ```sql -- 批处理1:创建临时表 CREATE TABLE #UserData (ID INT, Name NVARCHAR(50)); GO -- 批处理2:使用临时表(同一连接) INSERT INTO #UserData VALUES (1, 'Alice'); ``` - **与视图联合优化查询**[^5]: ```sql CREATE VIEW vw_RecentOrders AS ...; SELECT * INTO #TempOrders FROM vw_RecentOrders; -- 视图结果暂存 CREATE INDEX IX_Date ON #TempOrders(OrderDate); -- 添加索引加速分析 ``` --- #### 三、使用注意事项 1. **资源与性能** - 所有临时表共享 `tempdb` 空间,需监控其增长避免磁盘压力[^1]。 - **索引优化**:对大临时表创建索引(如 `CREATE INDEX IX_Col ON #Temp(Col)`)提升查询性能[^5]。 2. **作用域限制** - 本地临时表**不可跨会话访问**,全局临时表需谨慎管理连接状态[^2][^4]。 - 动态 SQL 中创建的临时表仅在**当前动态批处理**内有效[^5]。 3. **事务行为** - 对临时表的修改**可参与事务**,但事务回滚不影响表结构(仅回滚数据操作)。 --- #### 四、高级技巧 1. **动态SQL创建临时表** ```sql DECLARE @SQL NVARCHAR(MAX) = N' SELECT ProductID, SUM(Qty) AS TotalQty INTO #DynamicTemp FROM OrderDetails GROUP BY ProductID; '; EXEC sp_executesql @SQL; -- 临时表仅在动态SQL内有效[^5] ``` 2. **混合使用视图与临时表** ```sql -- 步骤1:视图简化基础查询 CREATE VIEW vw_SalesSummary AS ...; -- 步骤2:视图结果导入临时表并优化 SELECT * INTO #TempSales FROM vw_SalesSummary; CREATE INDEX IX_Region ON #TempSales(Region); -- 添加索引[^5] ``` 3. **全局临时表的会话协同** ```sql -- 会话1:创建全局表并插入数据 CREATE TABLE ##GlobalData (ID INT); INSERT INTO ##GlobalData VALUES (100); -- 会话2:读取数据(需在会话1保持连接时) SELECT * FROM ##GlobalData; ``` --- #### 五、临时表 vs 表变量 | **特性** | 临时表 | 表变量 | |------------------|---------------------------|---------------------| | **存储位置** | `tempdb` 磁盘 | 内存(小量时) | | **索引支持** | 支持完整索引 | 仅主键/唯一约束 | | **统计信息** | 自动更新 | 无统计信息 | | **事务回滚** | 数据保留 | 数据自动回滚 | | **适用场景** | 大数据量/复杂查询 | 小数据量/简单操作 | ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值