SQL Server:查询字符串中的变量无法在外部访问

时间:2014-09-24 03:00:45

标签: sql sql-server

我有一个基于动态字符串的SQL脚本,脚本的作用是创建来自不同表的数据并插入到临时表中。但是,在基于字符串的脚本之外无法访问已创建的临时表。关于如何访问临时表的任何想法?

下面是示例脚本,我只向您展示我需要的东西

DECLARE @x AS NVARCHAR(max)

SET @x = 'SELECT * into #persons FROM Persons Select * from #persons'

EXEC sp_executesql @x

--I need to access the temp table person below
Select #persons

以下是示例代码

的链接sample code and data

2 个答案:

答案 0 :(得分:2)

您可以通过在执行脚本的外部创建临时表来处理此问题。像这样:

DECLARE @x AS NVARCHAR(max);

SET @x = N'SELECT * into #persons FROM Persons;
           Select * from #persons';

create table #Persons (
    . . . 
);

insert into #Persons
    exec(@x);

有更简单的方法来检索单个值,但您似乎想要一个完整的表。

答案 1 :(得分:2)

由于范围问题(如您所见),子进程中创建的临时对象会在该子进程结束时自动删除。因此,您需要在运行EXEC之前创建临时表。

如果你真的有一个简单的查询,不需要动态组合在一起(可能不适用于此处,但我认为最好显示各种选项),那么你可以使用{{SELECT INTO进行WHERE 1 = 0 1}} condition或类似的东西,强制查询返回0行:

SELECT * INTO #tmp FROM sys.objects WHERE 1 = 0;

对于动态SQL,您只需要通过CREATE TABLE:

创建临时表
CREATE TABLE #tmp (....);

一旦完成其中任何一个,那么您可以通过sp_executesql运行查询,但是您无法保留SELECT INTO构造,因为它将在该子流程的本地创建一个新的临时表,让你回到开始的地方,无法访问sp_executesql之外的结果。您需要切换到使用INSERT INTO #tmp SELECT ...构造:

DECLARE @x NVARCHAR(MAX);

SET @x='INSERT INTO #tmp SELECT * FROM sys.objects;';

EXEC sp_executesql @x;

SELECT * FROM #tmp;

或者,您可以将INSERT INTO #tmp移到sp_executesql之外,在SET @x='SELECT * FROM sys.objects;'; INSERT INTO #tmp EXEC sp_executesql @x; 之上/之前(如在戈登的回答中):

sp_executesql

会话结束时会自动删除临时表,但您也可以显式删除它们。实际上,您遇到无法访问@@SPID中创建的临时表的问题的原因是因为临时表会自动清理: - )。

本地临时表(即单个#符号)是会话本地/ {{1}}所以如果5个用户或500个用户运行此查询无关紧要。