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

时间:2012-02-18 05:49:05

标签: sql sql-server-2005 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

这会导致错误:

  

Msg 208,Level 16,State 0,Line 25
  无效的对象名称' #tempadd'。

2 个答案:

答案 0 :(得分:4)

您的临时表仅限于动态查询的范围,因为它是在其中定义的。

您可以将select * from #tempadd语句添加到@sql查询的末尾。或者我认为你可以在动态查询之前定义#tempadd,它应该是可访问的,但我不确定。

答案 1 :(得分:1)

thanks to this blog

这里的问题是会话的范围。当我们通过EXEC或sp_executesql执行动态sql时,会为子会话创建一个新的作用域。会话关闭后,会立即删除在该会话中创建的任何对象。

我发现这个问题的一个解决方案是在“父”范围内创建表,然后只使用动态sql来修改表。为此,使用最少的colums集创建表。然后我们将ALTER TABLE语句与动态SQL一起使用。 Child会话可以访问在父会话中创建的对象,因此可以使用动态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

此表格可见,两列均会显示。