Sql-Server

我應該檢查儲存過程中是否存在臨時表?

  • May 8, 2020

是否有任何邊緣情況建議在儲存過程開始時顯式檢查、刪除和創建臨時表,而不是僅僅創建它們?

同樣,是否存在在儲存過程結束時顯式刪除它們比讓 SQL Server 清理它們更可取的情況?

關於檢查#tbl

在過程開始時檢查表是否存在(如果存在則將其刪除)並沒有什麼壞處,但這取決於您要如何處理該場景,並且在大多數情況下,它不可能已經存在無論如何(至少如果我們談論的是與該儲存過程中定義的相同的#temp 表)。

您使用以下命令檢查表是否存在:

IF OBJECT_ID('tempdb..#tablename') IS NOT NULL

您無法檢查 tempdb.sys.tables,因為實際名稱是,並且由於此潛在問題#tablename__________some hex code,您不應該使用。OBJECT_ID('...') > 0

當然,也有例外。想到的兩個:

  • 如果你呼叫了一切#temp,或者#t,或者#x,那麼在呼叫過程之前,這樣的表可能已經從外部範圍存在。CREATE TABLE #x您可以提出一個案例,在這種情況下您應該刪除它並創建您的新案例,但您也可以提出這是您想知道的錯誤情況 - 所以失敗可能沒關係。
  • 您實際上可能想要使用在外部範圍中創建的#temp 表,並且僅在尚未在該外部範圍中定義時才創建一個。這是可能的,我一直使用這種技術,但通常只在我想從我自己不能輕易操作的系統過程中擷取數據時(例如sp_helptext)。所以我可能會這樣做:
CREATE TABLE #x([Text] NVARCHAR(MAX));
GO
CREATE PROCEDURE dbo.myhelp @p SYSNAME
AS
 INSERT #x EXEC sp_helptext @p;
GO
EXEC dbo.myhelp N'dbo.myhelp'; -- inception
GO
SELECT [Text] FROM #x;

即使#x在外部定義,這也有效。這是一個糟糕的例子,因為我寧願使用sys.sql_modules,但我相信您明白這一點,並且可以設想如何使用自己的程序來做到這一點。

在 DROP TABLE #tbl 上;

我認為您是否應該在程序結束時明確刪除#temp 表非常有爭議,因此將主要基於意見而關閉;請參閱Paul White的這些優秀部落格文章,徹底閱讀它們,如果您的所有問題都沒有得到回答,請返回並製定一個具體問題:

引用自:https://dba.stackexchange.com/questions/73514