我有一个基于动态字符串的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答案 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个用户运行此查询无关紧要。