error in creating a temp table using dynamic sql

2019-09-21 20:48发布

问题:

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
Invalid object name '#tempadd'.

回答1:

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. Alternatively I think you can define #tempadd before your dynamic query and it should be accessible, but I'm not certain on that.



回答2:

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. 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. 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. The Child session has access to the objects created in the parent session so the table can be modified with dynamic 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.