程序的多個實例可以同時創建相同的#Temp 嗎?
我有一個將數據插入#temp 表的過程。在對數據執行某些操作後,它將數據從#temp 表儲存到其他表。
我無法同時執行此過程的多個實例。為什麼?我們在多個選項卡中創建具有相同名稱的#temp 表。那麼為什麼我們不能對臨時表的多個實例做同樣的事情呢?
有什麼解決辦法嗎?
例子:
--exec dbo.testing_temp_table CREATE PROCEDURE [dbo].[testing_temp_table] AS BEGIN SET NOCOUNT ON; -- Insert statements for procedure here IF OBJECT_ID('tempdb..#temp_1') IS NOT NULL drop table #temp_1 select * into #temp_1 from dbo.Emp END
“我不能同時執行這個程序的多個實例。為什麼?”
您能否澄清“無法執行”的含義?你有錯誤嗎?
現在,您不需要使用 IF OBJECT_ID() 來檢查儲存過程中是否存在表。
SQL Server 將為儲存過程的每個實例創建一個臨時表的實例,並且它僅對創建範圍(在本例中為儲存過程)和內部範圍可見(例如,如果您呼叫另一個子範圍)您的程式碼中的過程。程序完成後,臨時表將消失。
在幕後,查詢處理器將一些唯一的字元串附加到 TempDB 中每個實例的表名。
BOL 包含所有詳細資訊:CREATE TABLE (Transact-SQL)
–響應 OP 關於生成相同後綴的儲存過程的評論。–
您在這裡沒有給予 SQL Server 足夠的信任。如果您的說法是正確的,這將是一個重大錯誤;完全支持執行使用臨時表的儲存過程的多個實例。
我懷疑您是在單個連接上測試它,並且看到在重新執行相同的過程時,您會得到相同的後綴。這是對從同一會話重複執行重用後綴的優化。
你應該測試的是:
CREATE PROCEDURE P AS BEGIN CREATE TABLE #T(Col1 INT); WAITFOR DELAY '00:00:10'; SELECT * FROM TempDB.sys.tables; END
然後在兩個或多個連接上,並發執行
EXEC P
這是我的想法:
高溫高壓
你的問題是范圍。@SQLRaptor 在他上面的回復中是完全正確的,但如果你這樣看它可能會有所幫助:
如果您創建臨時表,則它的範圍僅限於您的會話。換句話說,它會一直存在,直到您的會話關閉或您刪除它。您所期望的是將您的臨時表限定為您的儲存過程(不是這種情況),就像表變數一樣。例子:
-- Query window (otherwise known as session in this case) Create #temp1 (temp table) Create @temp1 (table variable) -- Run a stored procedure Create #temp2 (temp table) Create @temp2 (table variable) -- Currently all four exist. -- On leaving the stored procedure the following exist: -- #temp1 -- #temp2 -- @temp1 -- Rerun the same stored procedure You attempt to create #temp2 but it fails because #temp2 still exists.
現在,如果您完全離開會話(查詢視窗),那麼它們都會消失。
還有全域臨時表。以##開頭的那些。這些僅限於所有會話,並且只有在沒有人再使用它們時才會消失。
基本上,除非您出於某種原因計劃重新使用臨時表,否則將其放在 SP 的末尾。所以像這樣:
--exec dbo.testing_temp_table CREATE PROCEDURE [dbo].[testing_temp_table] AS BEGIN SET NOCOUNT ON; -- Insert statements for procedure here select * into #temp_1 from dbo.Emp -- The rest of your code goes here DROP TABLE #temp_1 END