如果 sp_ExecuteSql 创建一个新会话,我怎么可以访问在动态 SQL 之外创建(在执行之前)的本地临时表?

J.D*_*.D. 4 sql-server dynamic-sql session temporary-tables sql-server-2016

如果本地临时表仅对当前会话可用,并且 sp_ExecuteSql 创建一个新会话来执行传递给它的动态 SQL 字符串,那么该动态 SQL 查询如何访问在执行 sp_ExecuteSql 的会话中创建的临时表。

换句话说,为什么这样做:

SELECT 1 AS TestColumn
INTO #TestTempTable

DECLARE @DS NVARCHAR(MAX) = 'SELECT * FROM #TestTempTable'
EXEC sp_EXECUTESQL @DS
Run Code Online (Sandbox Code Playgroud)

结果:

动态 SQL 选择的临时表结果

我之所以不能做相反的事情(在动态 SQL 中创建临时表,然后在执行会话中的动态 SQL 查询之外访问它),我的理解是因为 sp_ExecuteSql 在新会话下执行。

Ran*_*gen 9

答案瑞摩斯Rusanu

动态 SQL 在与调用代码相同的会话中运行。问题不是会话,而是范围。您的动态 SQL 在 sp_executesql 调用中创建临时表,因此创建的 #temp 表仅在该 sp_executesql 调用中可见,如 MSDN 中所述:

您可以sp_executesql 通过运行以下命令来验证您是否在调用中使用了相同的会话:

DECLARE @DS NVARCHAR(MAX) = 'SELECT @@SPID'
EXEC sp_EXECUTESQL @DS
Run Code Online (Sandbox Code Playgroud)

知道sp_executesql在不同的范围内运行而不是在不同的会话下运行,添加在临时表文档中找到的信息:

临时表在超出范围时会自动删除,除非使用 DROP TABLE 显式删除:

关于临时表可见性的相同来源:

本地临时表仅在当前会话中可见

作用域与会话的这些差异解释了为什么您可以从sp_executesql调用中访问临时表,但反过来却不能。