2011-05-10 54 views
4

比较下面的存储过程:什么是存储过程中的exec内临时表的范围规则?

CREATE PROCEDURE testProc1 
AS 
    SELECT * INTO #temp FROM information_schema.tables 
    SELECT * FROM #temp 
GO 

CREATE PROCEDURE testProc2 
AS 
    EXEC('SELECT * INTO #temp FROM information_schema.tables') 
    SELECT * FROM #temp 
GO 

现在,如果我跑testProc1,它的工作原理,并#temp似乎只存在于该呼叫的持续时间。然而,testProc2似乎并没有在所有的工作,因为我得到一个Invalid object name '#temp'错误讯息。

为什么区分,如何使用临时表到SELECT * INTO如果源表名是存储过程的参数并且可以有任意的结构?

请注意,我使用的是Microsoft SQL Server 2005中

回答

6

从BOL:

本地临时表可见 仅在当前会话中...... 临时表自动 下降,当他们走出去的范围,除非 使用DROP TABLE 显式删除

的第一和第二程序之间的区别是,在第一,该表在相同的范围内,它是选自所定义;第二,在EXEC()在自己的范围内创建表,所以在这种情况下,选择失败...

但是请注意,以下的作品就好了:

CREATE PROCEDURE [dbo].[testProc3] 
AS 
    SELECT * INTO #temp FROM information_schema.tables 
    EXEC('SELECT * FROM #temp') 
GO 

而且它的工作原理因为EXEC的范围是存储过程范围内的子项。当该表在父范围中创建时,它也适用于任何子项。

为了给你一个很好的解决方案,我们需要更多地了解你正在试图解决的问题......但是,如果你只是需要从创建的表中选择,进行选择在孩子范围内工作得很好:

CREATE PROCEDURE [dbo].[testProc4] 
AS 
    EXEC('SELECT * INTO #temp FROM information_schema.tables; SELECT * FROM #temp') 
GO 
+0

把所有到一个EXEC作品。谢谢。 – polygenelubricants 2011-05-10 23:04:27

0

你可以尝试使用一个全局临时表(名为##温度不#TEMP)。但请注意,其他连接也可以看到此表。