Sql-Server

程序的多個實例可以同時創建相同的#Temp 嗎?

  • December 25, 2020

我有一個將數據插入#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

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