首页 > 解决方案 > Msn SSMS 中的动态 SQL 代码中的临时表“存在”多长时间?

问题描述

我的临时表在我的代码中“存活”的时间不够长。

我的问题是这样的:我想在一个“代码变量”中创建一个临时表并稍后使用它。我的代码结构示例如下:

declare @RW varchar(MAX)

set @RW = '
select *
into #temptable
from table1'
exec(@RW)

--Alots of other code.

select *
from #temptable

这会导致错误消息“无效的对象名称'#temptable'。很明显我的临时表不再存在。但我已经检查过该表是在第一步中创建的。例如以下代码作品:

declare @RW varchar(MAX)

set @RW = '
select *
into #temptable
from table1

select *
from #temptable'
exec(@RW)

所以我的猜测是临时表只存在于它的代码变量中。有没有办法创建一个寿命更长的临时表?或者,我只是需要接受它的本来面目还是我错过了什么?我有一个不是很有效的解决方案。我在想的是创建一个我稍后删除的常规表。这将意味着大量写入磁盘,但这是我使用的系统可以生存但不满意的东西。有没有其他方法来处理这个?

标签: sqlsql-server

解决方案


临时表仅在声明它的范围内持续存在。对于断开连接时的“正常”连接。例如,如果您使用 SSMS 并打开一个查询窗口并运行CREATE TABLE #T (ID int);它将创建表。由于您仍处于连接状态,因此该表不会被删除并且仍然存在。如果您再次运行该语句(不删除它),您将收到它已经存在的错误。关闭该查询窗口后,临时表将被删除。

对于动态语句,范围是该动态语句的持续时间。这意味着一旦动态语句完成,表就会被删除:

EXEC sys.sp_executesql N'CREATE TABLE #T (ID int);';

SELECT *
FROM #t;

请注意此错误,因为创建表的范围已完成,因此已删除。

如果您使用动态语句创建临时表,则需要在动态语句中对所述临时表进行所有引用。

否则,如果您需要在语句之外引用它,我个人发现我在 中创建了一个“永久”对象tempdb,然后再进行清理。

EXEC sys.sp_executesql N'CREATE TABLE tempdb.dbo.T (ID int);';

SELECT *
FROM tempdb.dbo.T;

DROP TABLE tempdb.dbo.T;

如果实例也重新启动,这些表仍然会被删除。


请注意,“全局”临时表的行为略有不同。由于全局临时表可以在任何连接中被引用,只要它存在。这意味着在创建它的范围结束时,另一个连接可能正在使用该表。结果,全局临时表一直存在,直到声明的范围结束并且没有其他活动连接使用该对象。这意味着可以在另一个连接中批量删除对象。


推荐阅读