sql - 存储过程中 exec 内的临时表的作用域规则是什么?

标签 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

现在,如果我运行 testProc1,它就会工作,并且 #temp 似乎只在该调用期间存在。但是,testProc2 似乎根本不起作用,因为我收到了 Invalid object name '#temp' 错误消息。

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

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

最佳答案

来自 BOL:

Local temporary tables are visible only in the current session... ... Temporary tables are automatically dropped when they go out of scope, unless explicitly dropped using 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

关于sql - 存储过程中 exec 内的临时表的作用域规则是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5955074/

相关文章:

sql - 如何给表添加复合主键

SQL Server : select where row was X but is not now X

PHP/SQL 问题 : Data from sql wont display

sql - 如何将记录从互连表复制到不同数据库中的另一个表?

sql - 什么时候应该使用 CROSS APPLY 而不是 INNER JOIN?

mysql - 异常Mysql存储过程调用

sql - (Flex 中的 Mysql - 有什么好的库吗?

sql - 基于key的随机SELECT查询

sql-server - 如何从存储过程返回值中获取COUNT?

entity-framework - 如何在 Entity Framework 6中执行存储过程而不返回结果?