全局临时表以##开头,跨会话可见,生命周期由最后一个引用它的会话决定;创建时表名须静态确定,动态sql中不可拼接##前缀,且跨exec批次不可见。

全局临时表名必须用双井号开头,且不能拼接字符串直接写在 CREATE TABLE 语句里
SQL Server 中的全局临时表(##temp_table)作用域是跨会话的,但生命周期随最后一个引用它的会话结束而销毁。你不能在存储过程中写 CREATE TABLE ##t (id INT) 后再动态改名或复用——名字必须在编译期可静态识别。但实际需求常是“按参数生成不同结构的临时表”,这时必须用动态 SQL。
常见错误是试图拼接表名后直接执行:EXEC('CREATE TABLE ##' + @suffix + ' (col1 INT)'),这会导致语法错误,因为 SQL Server 不允许在动态 SQL 中创建以 ## 开头的全局临时表(解析器会拒绝识别为合法对象名)。正确做法是把整个语句构造成完整字符串,并确保 ## 是字面量的一部分:
DECLARE @sql NVARCHAR(MAX) = 'CREATE TABLE ##dynamic_temp (id INT, name VARCHAR(50));'; EXEC sp_executesql @sql;
注意:这里 ##dynamic_temp 是硬编码的,不是拼接出来的。若真需参数化表名,只能拼接中间部分,且必须严格校验输入防注入:'##temp_' + REPLACE(@user_input, '''', '''''')。
动态创建的全局临时表在 EXEC 调用结束后仍存在,但调用方连接断开就自动删除
很多人误以为 EXEC sp_executesql @sql 执行完,里面建的 ##temp 就消失了。其实不会——全局临时表的生命周期绑定的是「创建它的会话」和「最后使用它的会话」。只要当前连接没关闭,后续语句就能直接查 SELECT * FROM ##dynamic_temp,无需再次声明。
但要注意两点:
- 如果存储过程里用
EXEC新启了一个子会话(比如通过sp_start_job或链接服务器),那个子会话创建的##temp对主会话不可见 - 连接池环境下,下次从池里取出的连接可能复用了之前建过同名
##temp的会话,导致CREATE TABLE ##x报“对象已存在”错误 - 显式删除比依赖自动清理更可靠:
IF OBJECT_ID('tempdb..##dynamic_temp') IS NOT NULL DROP TABLE ##dynamic_temp;
删除前必须检查 tempdb..sysobjects,否则 DROP TABLE 可能报错中断流程
全局临时表物理存在于 tempdb,但名字带 ## 前缀,所以不能用常规的 OBJECT_ID('##mytable') 判断——它返回 NULL。正确方式是查 tempdb 系统视图:
IF EXISTS (
SELECT 1 FROM tempdb.sys.tables
WHERE name LIKE '##dynamic_temp%'
)
DROP TABLE ##dynamic_temp;
更稳妥的做法是加 TRY...CATCH 或用 IF OBJECT_ID('tempdb..##dynamic_temp') IS NOT NULL ——虽然文档说 OBJECT_ID 对全局临时表支持有限,但在 SQL Server 2016+ 实测中,只要表名确定、未被其他会话抢先删掉,这个判断是有效的。不过仍建议优先用 tempdb.sys.tables 查询,避免版本差异风险。
跨批次引用时,全局临时表对后续 EXEC 不可见,除非用同一连接串行执行
如果你在存储过程中这样写:
EXEC('CREATE TABLE ##t(a INT)');
EXEC('SELECT * FROM ##t'); -- 这里会报“对象名 '##t' 无效”
原因在于每个 EXEC 都开启一个独立的作用域,第一个 EXEC 创建的 ##t 在其执行结束后,虽未被销毁(因连接还在),但第二个 EXEC 的上下文无法“看到”它——这是 SQL Server 的作用域隔离机制。解决方法只有两个:
- 把所有操作写进同一个动态 SQL 字符串里:
EXEC('CREATE TABLE ##t(a INT); SELECT * FROM ##t;') - 改用本地临时表
#t(如果只需本会话内用),它天然支持跨EXEC引用 - 或者放弃动态 SQL,改用表变量
@t TABLE(...),但表变量不支持 DDL 和索引,功能受限
真正需要全局临时表的场景其实很少——多数时候只是误以为要跨存储过程共享数据。实际上,用输出参数、临时表预创建、或把逻辑合并到单个过程里,反而更稳。











