【问题标题】:Temporary stored procedure scope临时存储过程范围
【发布时间】:2016-09-29 17:52:35
【问题描述】:

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

使用动态 SQL(EXECdbo.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'.

LiveDemo

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

-- 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;

LiveDemo2

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

【问题讨论】:

  • 仅供参考:如果对象在 tempdb.sys.objects 中有条目,即使在 scope.querying 系统目录可能提供更多信息之后,我们也能看到这一点

标签: sql sql-server tsql stored-procedures sql-server-2012


【解决方案1】:

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

只要定义它的会话(通过 exec)关闭,proc 就会消失。

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

见: 您创建的任何表都对

中的 EXEC() 上下文可见

https://technet.microsoft.com/en-us/library/aa175921%28v=sql.80%29.aspx

【讨论】:

  • 您能提供文档的准确报价吗? The reason it keeps it around outside the exec because SQL Server can reuse the proc's query plan. 拥有WITH RECOMPILE的SP怎么办?
  • 引用来自我引用的 URL,在引用页面底部附近的标题为:EXEC() 的部分中。由于 SQL Server 已经确定只要调用方处于活动状态,它就会保留 proc,使用“with recompile”将强制 SQL Server 每次都重新编译,但它仍然可以在 exec 之外访问。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-14
  • 2012-01-28
  • 2014-12-22
  • 2011-09-29
  • 2016-08-02
相关资源
最近更新 更多