Sql 存储过程中exec中临时表的作用域规则是什么?
比较以下存储过程:Sql 存储过程中exec中临时表的作用域规则是什么?,sql,tsql,stored-procedures,exec,temp-tables,Sql,Tsql,Stored Procedures,Exec,Temp Tables,比较以下存储过程: 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 现在,如果我
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似乎根本不起作用,因为我收到了一条无效的对象名“temp”错误消息
如果源表名是存储过程的一个参数,并且可以具有任意结构,那么为什么会有这种区别,以及如何使用临时表来选择*INTO
请注意,我使用的是Microsoft SQL Server 2005。来自BOL:
本地临时表可见
只有在本届会议上。。。
临时表是自动生成的
当它们超出范围时就会掉下来,
除非使用DROP显式删除
桌子
第一个过程和第二个过程的区别在于,在第一个过程中,表的定义范围与其所选范围相同;在第二种情况下,EXEC在自己的作用域中创建表,因此在本例中选择失败
但是,请注意,以下操作非常有效:
CREATE PROCEDURE [dbo].[testProc3]
AS
SELECT * INTO #temp FROM information_schema.tables
EXEC('SELECT * FROM #temp')
GO
CREATE PROCEDURE [dbo].[testProc4]
AS
EXEC('SELECT * INTO #temp FROM information_schema.tables; SELECT * FROM #temp')
GO
它之所以有效,是因为EXEC的作用域是存储过程作用域的子级。在父作用域中创建表时,它也存在于任何子作用域中
为了给你一个好的解决方案,我们需要更多地了解你试图解决的问题。。。但是,如果您只需要从创建的表中进行选择,那么在子范围中执行选择就可以了:
CREATE PROCEDURE [dbo].[testProc3]
AS
SELECT * INTO #temp FROM information_schema.tables
EXEC('SELECT * FROM #temp')
GO
CREATE PROCEDURE [dbo].[testProc4]
AS
EXEC('SELECT * INTO #temp FROM information_schema.tables; SELECT * FROM #temp')
GO
您可以尝试使用名为temp not temp的全局临时表。但是,请注意,其他连接也可以看到此表