Sql-Server

如果塊無法在過程中創建臨時表

  • December 28, 2018

我試圖在一個過程中做到這一點:

DECLARE @a bit = 1;
BEGIN
   SELECT * INTO #aTemp FROM OPENROWSET( ... );

   IF @a = 0
   BEGIN
       SELECT ... INTO #bTemp FROM #aTemp;
   END
   ELSE
   BEGIN
       SELECT ... INTO #bTemp FROM #aTemp;
   END
END

我得到錯誤:

Msg 2714, Level 16, State 1, Line 10
There is already an object named '#bTemp' in the database.

為什麼會發生這種情況,是否有解決方法?

更新

我試圖按照這裡DROP的建議添加一個語句,但它仍然不起作用:

DECLARE @a bit = 1;
BEGIN
   SELECT * INTO #aTemp FROM OPENROWSET( ... );

   IF @a = 0
   BEGIN
       IF OBJECT_ID('[tempdb]..#bTemp') IS NOT NULL
       BEGIN
           DROP TABLE #bTemp;
       END

       SELECT ... INTO #bTemp FROM #aTemp;
   END
   ELSE
   BEGIN
       IF OBJECT_ID('[tempdb]..#bTemp') IS NOT NULL
       BEGIN
           DROP TABLE #bTemp;
       END

       SELECT ... INTO #bTemp FROM #aTemp;
   END
END

根據文件

如果在單個儲存過程或批處理中創建了多個臨時表,則它們必須具有不同的名稱。

我最終在塊之前創建了表格,IF如下所示:

DECLARE @a bit = 1;
BEGIN
   IF OBJECT_ID('[tempdb]..#bTemp') IS NOT NULL
   BEGIN
       DROP TABLE #bTemp;
   END

   CREATE TABLE #bTemp (
       [c] int);

   IF @a = 0
   BEGIN
       INSERT INTO #bTemp
       SELECT 1 AS [c];
   END
   ELSE
   BEGIN
       INSERT INTO #bTemp
       SELECT 1 AS [c];
   END

   DROP TABLE #bTemp;
END

這不是問題的答案,只是向@SebastienMeine 展示##global 臨時表如何殺死並發。

在一個視窗中,執行以下操作:

CREATE PROCEDURE dbo.floob1
 @p INT
AS
BEGIN
 SET NOCOUNT ON;

 SELECT a = @p INTO ##floob;
END
GO

CREATE PROCEDURE dbo.floob2
AS
BEGIN
 SET NOCOUNT ON;

 SELECT a FROM ##floob;
END
GO

EXEC dbo.floob1 @p = 1;
WAITFOR DELAY '00:01:00';
EXEC dbo.floob2;

結果:

a
----
1

然後打開另一個視窗,執行以下操作:

BEGIN TRY
 EXEC dbo.floob1 @p = 2;
END TRY
BEGIN CATCH
 PRINT 'Something bad happened.';
END CATCH
GO
EXEC dbo.floob1 @p = 2;
GO
EXEC dbo.floob2;

結果:

發生了不好的事情。

消息 2714,級別 16,狀態 6,過程 floob1

數據庫中已經有一個名為“##floob”的對象。

a
----
1

所以##table 仍然存在,即使它創建的過程早已完成。

然後在第一個視窗完成後,再次嘗試在第一個視窗中執行此部分:

EXEC dbo.floob1 @p = 1;

結果:

消息 2714,級別 16,狀態 6,過程 floob1

數據庫中已經有一個名為“##floob”的對象。

因此,即使同一使用者只是嘗試再次創建,##table 仍然存在。

這說明:

  1. 一次只有一個使用者可以有效地呼叫此過程
  2. 不要打擾刪除#temp 表(我對此持懷疑態度)的標準建議不適用於##temp 表。

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