Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/83.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 临时存储过程作用域_Sql_Sql Server_Tsql_Stored Procedures_Sql Server 2012 - Fatal编程技术网

Sql 临时存储过程作用域

Sql 临时存储过程作用域,sql,sql-server,tsql,stored-procedures,sql-server-2012,Sql,Sql Server,Tsql,Stored Procedures,Sql Server 2012,SQL Server支持临时表(本地和全局) 使用动态SQL(EXEC或dbo.sp_executesql),我们可以创建新的上下文,并且本地临时表仅在动态SQL块中可见,在外部不可见 -- Normal table EXEC ('CREATE TABLE tab(i INT); INSERT INTO tab(i) VALUES (1)'); SELECT * FROM tab; -- Global temporary table EXEC ('CREATE TABLE ##tab(i IN

SQL Server
支持临时表(本地和全局)

使用动态SQL(
EXEC
dbo.sp_executesql
),我们可以创建新的上下文,并且本地临时表仅在动态SQL块中可见,在外部不可见

-- Normal table
EXEC ('CREATE TABLE tab(i INT); INSERT INTO tab(i) VALUES (1)');
SELECT * FROM tab;

-- Global temporary table
EXEC ('CREATE TABLE ##tab(i INT); INSERT INTO ##tab(i) VALUES (2)');
SELECT * FROM ##tab;

-- Local temporary table
EXEC ('CREATE TABLE #tab(i INT); INSERT INTO #tab(i) VALUES (3)');
SELECT * FROM #tab;
-- Invalid object name '#tab'.

现在,让我们对存储过程进行同样的尝试:

-- Normal procedure
EXEC ('CREATE PROCEDURE my_proc AS SELECT 1 AS col;');
EXEC my_proc;

-- Global temporary procedure
EXEC ('CREATE PROCEDURE ##my_proc AS SELECT 2 AS col;');
EXEC ##my_proc;

-- Local temporary procedure
EXEC ('CREATE PROCEDURE #my_proc AS SELECT 3 AS col;');
EXEC #my_proc;


问题是为什么本地临时过程的行为不同,并且在EXEC外部可见?

之所以将其保留在EXEC外部,是因为SQL Server可以重用proc的查询计划

一旦定义proc的会话(通过exec)关闭,proc就会消失

MS非常小心地指出临时“表”(带有一个#符号的表)是上下文的本地表,调用程序不可见

见: 您创建的任何表都对中的EXEC()上下文可见


你能提供doc的准确报价吗<代码>将其保留在exec之外的原因,因为SQL Server可以重用proc的查询计划对于具有带重新编译功能的
的SP来说是什么?
?引文来自我引用的URL,并位于引用页面底部标题为:EXEC()的部分。由于SQL Server已确定只要调用方处于活动状态,它就会保持该过程,因此使用“with recompile”将强制SQL Server每次重新编译,但在exec.FYI之外仍可以访问该过程:如果对象在tempdb.sys.objects中有条目,我们甚至可以在范围之后看到这一点。查询系统目录可能会提供更多信息