2011-05-10 52 views
4

比較下面的存儲過程:什麼是存儲過程中的exec內臨時表的範圍規則?

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中

回答

6

從BOL:

本地臨時表可見 僅在當前會話中...... 臨時表自動 下降,當他們走出去的範圍,除非 使用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 
+0

把所有到一個EXEC作品。謝謝。 – polygenelubricants 2011-05-10 23:04:27

0

你可以嘗試使用一個全局臨時表(名爲##溫度不#TEMP)。但請注意,其他連接也可以看到此表。