简体   繁体   English

使用动态SQL创建临时表时出错

[英]error in creating a temp table using dynamic sql

declare @TableName nvarchar(max)
set @TableName='addresses'

DECLARE @sql NVARCHAR(MAX)
set @sql= 'create table #tempadd ( '
SELECT @sql=@sql + STUFF( -- Remove first comma  
(  
 SELECT  ', ' + column_name+' '+ case when DATA_TYPE='varchar' then DATA_TYPE +'(500)' else DATA_TYPE end   FROM -- create comma separated values  
 (  
   SELECT column_name,DATA_TYPE FROM information_schema.columns  where table_name = @TableName --Your query here  
 ) AS T FOR XML PATH('')  
)  
,1,1,'')  

set @sql =@sql+' ) '


print @sql 

--SET @sql='SELECT * into #tempadd FROM '+@TableName+  ' WHERE 1=2'


EXEC sp_executesql @sql

select * from #tempadd

This results in an error: 这会导致错误:

Msg 208, Level 16, State 0, Line 25 消息208,级别16,状态0,第25行
Invalid object name '#tempadd'. 无效的对象名称“ #tempadd”。

Your temp table is limited to the scope of your dynamic query since it is defined within. 由于临时表是在其中定义的,因此它仅限于动态查询的范围。

You could add your select * from #tempadd statement to the end of your @sql query. 您可以将您的select * from #tempadd语句添加到@sql查询的末尾。 Alternatively I think you can define #tempadd before your dynamic query and it should be accessible, but I'm not certain on that. 另外,我认为您可以在动态查询之前定义#tempadd,并且应该可以访问它,但是我不确定。

thanks to this blog 感谢这个博客

The problem here is the scope of the session. 这里的问题是会话的范围。 When we execute dynamic sql via EXEC or sp_executesql a new scope is created for a child session. 当我们通过EXEC或sp_executesql执行动态sql时,将为子会话创建新的作用域。 Any objects created in that session are dropped as soon as the session is closed. 会话关闭后,该会话中创建的所有对象都会被删除。

One solution I have found for this problem is creating the table in the "parent" scope and then just using dynamic sql to modify the table. 我发现的针对此问题的一种解决方案是在“父”范围内创建表,然后仅使用动态sql修改表。 For this to work a table is created with a minimum set of colums. 为此,需要创建带有最少列集的表。 And then we use the ALTER TABLE statement with dynamic SQL. 然后,我们在动态SQL中使用ALTER TABLE语句。 The Child session has access to the objects created in the parent session so the table can be modified with dynamic sql: 子会话可以访问在父会话中创建的对象,因此可以使用动态sql修改表:

DECLARE @SQL NVARCHAR(4000)
CREATE TABLE #Temp ( id int null)
SELECT @SQL = 'ALTER #Temp ADD Col1 int null'
EXEC (@SQL)
SELECT * FROM #Temp
DROP TABLE #Temp

This table is visible and both columns will show up. 该表可见,并且两列都将显示。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM