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'。
答案 0 :(得分:4)
您的临时表仅限于动态查询的范围,因为它是在其中定义的。
您可以将select * from #tempadd
语句添加到@sql
查询的末尾。或者我认为你可以在动态查询之前定义#tempadd,它应该是可访问的,但我不确定。
答案 1 :(得分:1)
这里的问题是会话的范围。当我们通过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
此表格可见,两列均会显示。