2010-07-26 134 views
7

我正在使用臨時表#tempTable在我的存儲過程 - 這是我利用來運行我的ASP.net報告(報告服務)臨時表範圍?

我做這樣的事情

如。代碼

SELECT * INTO #tempTable FROM Contacts WHERE ContactID < 10 

然後,我使用類似

SELECT o.* FROM #tempTable t INNER JOIN Orders o ON t.ContactID =o.ContactID 

到值又名結果返回給我的報告,該存儲過程

我不擺脫我#tempTable的

即我不這樣做

DROP TABLE #tempTable 

我已經讀過,臨時表的範圍只適用於存儲過程 - 所以正在做上述必要的 - 如果我不做以上問題,我將在未來遇到什麼問題

+0

@Tom:這可能是一個簡單的例子。有時他們是必需的。 – Hogan 2010-07-26 23:27:58

回答

2

它被認爲是良好的編碼習慣明確刪除您創建的每個臨時表。如果您通過SQL Server Management Studio/Query Analyzer執行腳本,臨時表將一直保留,直到您明確放棄它們或直到您關閉會話。

+0

但是,如果我通過ASP.net應用程序調用它們? – soldieraman 2010-07-26 08:26:11

+1

在存儲過程中創建的本地臨時表將在存儲過程完成時自動刪除 。但是,我傾向於在我不再需要它們時立即放棄它們。我想這在複雜的長時間運行的存儲過程中更重要。 – 2010-07-26 22:31:47

1

一般來說,你可能不會因爲不放棄臨時表而出現問題。本地臨時表具有會話範圍或SP範圍。當會話關閉或SP完成時它會自動放下。

但是,您通過定期遵循此練習確實會增加出現問題的風險。例如,如果您不使用SP,但從ASP .net提交SELECT語句並保持打開SQL Server連接,臨時表將繼續存在。繼續使用連接和其他臨時表將導致tempdb隨着時間的推移而增長。

我也支持在這種情況下使用臨時表的其他意見。如果您創建沒有臨時表的解決方案,則可能會有更快的報告並避免使用DROP臨時表命令。

10

首先,過程完成後,將刪除在過程中創建的本地臨時表。從BOL on Create Table

在存儲過程完成時,會自動刪除在存儲過程中創建的本地臨時表。該表可以由創建該表的存儲過程執行的任何嵌套存儲過程引用。該表不能被調用創建該表的存儲過程的進程引用。

如果您的數據訪問代碼正確地打開連接,調用存儲過程然後關閉連接,則會在該過程中創建的臨時表被有效銷燬。

我說「有效」提出另一個觀點。我不建議在過程結束時刪除臨時表,儘管在創建臨時表之前我會添加一個檢查並在存在的情況下刪除它(例如if object_id('tempdb..#Foo') is not null)。反對在最後放棄臨時表的觀點是,通過調用Drop語句,您迫使SQL Server花費資源在您等待過程結束時耗費時間銷燬表。相反,如果讓它超出範圍,則您的過程會立即結束,並讓SQL Server在自己選擇的時間銷燬表。

7

#Temp表的範圍僅限於您的會話和批處理的生命週期,意味着其他人無法看到您的臨時表,並且任何人都可以使用相同的名稱創建自己的#Temp表。一旦你的會話或批處理結束,SQL Server將清理臨時表。

在另一個注意事項## Temp表像行爲像一個普通的表。每個人都可以看到它,並且不能超過1個##具有相同名稱的臨時表。 SQL Server將在服務器重新啓動時清除這些## Temp表。

+7

這並不完全準確。臨時表不限於批次的範圍 - 無論批次如何,它們都可以在整個會話中存活。也就是說,你可以創建一個臨時表,使用'GO',並且臨時表將與其數據一起存在。 – ean5533 2013-01-03 18:23:43

+1

我遇到了.NET SqlCommand中創建的臨時表持續存在不會持續到第二個SqlCommand的情況,即使它們在同一個打開的連接上運行。 – Triynko 2015-02-25 21:03:07