2016-05-31 77 views
3

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以外可見?

+0

FYI:如果對象在tempdb.sys.objects項,我們都能夠看到這甚至在scope.querying系統目錄後可能提供更多信息 – TheGameiswar

回答

0

因爲SQL Server可以重複使用proc的查詢計劃,所以它保留在exec之外。

只要定義了它的會話(通過exec),proc就會關閉。

MS非常小心地指出temp'tables'(一個帶#號)是上下文本地的,對調用程序不可見。

參見: 任何你創建表是在EXEC()的上下文中可見

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

+0

您能否提供來自doc的確切報價? '因爲SQL Server可以重用proc的查詢計劃,所以它保留在exec之外。 '帶有'WITH RECOMPILE'的SP是什麼? – lad2025

+0

引用來自我引用的URL,位於引用頁面底部附近的EXEC()一節中。由於SQL Server已經確定,只要調用人員使用「with recompile」激活,它就會保留proc,這將強制SQL Server每次重新編譯,但仍然可以在exec之外訪問。 –