這裏內部重複的臨時表的情況是:創建嵌套的存儲過程
步驟1創建臨時表(#MYTABLE),並調用步驟2.步驟2也嘗試創建#MYTABLE,與不同的列。當過程2嘗試將數據插入到#MYTABLE中時,會發生抱怨「列名無效」的錯誤。我對這個兩個問題:內部程序2創建#MYTABLE當
1)如果不是系統抱怨嗎?我明白爲什麼它不能在編譯時反對,但是在運行時我會期待一個錯誤。 2)鑑於它不會抱怨創建,事實上當你在程序2中的#MYTABLE中選擇SELECT時,你會看到新列,爲什麼它會抱怨INSERT?
以下是代碼。取消註釋INSERT語句會得到錯誤。
(我知道了很多辦法來解決這個情況,所以我並不需要有關的反應。我只是想知道發生了什麼。)
IF OBJECT_ID(N'dbo.MYPROC1', N'P') IS NOT NULL
DROP PROCEDURE dbo.MYPROC1;
GO
CREATE PROCEDURE dbo.MYPROC1
AS
CREATE TABLE dbo.#MYTABLE (Name VARCHAR(256));
SELECT
'DO NOTHING 1' AS TABLENAME;
EXEC dbo.MYPROC2;
GO
IF OBJECT_ID(N'dbo.MYPROC2', N'P') IS NOT NULL
DROP PROCEDURE dbo.MYPROC2;
GO
CREATE PROCEDURE dbo.MYPROC2
AS
SELECT
'INSIDE PROC 2 BEFOREHAND' AS TABLENAME
,*
FROM
dbo.#MYTABLE;
CREATE TABLE dbo.#MYTABLE
(
Name VARCHAR(256)
,LastName VARCHAR(256)
);
--INSERT INTO dbo.#MYTABLE
-- (Name, LastName)
-- SELECT
-- 'BARACK'
-- ,'OBAMA';
SELECT
'INSIDE PROC 2 AFTERWARDS' AS TABLENAME
,*
FROM
dbo.#MYTABLE;
--INSERT INTO dbo.#MYTABLE
-- (Name, LastName)
-- SELECT
-- 'BARACK'
-- ,'OBAMA';
SELECT
'DO NOTHING 2' AS TABLENAME;
GO
EXEC MYPROC1;
這個答案很好地解釋了問題1,謝謝。但我仍然不明白爲什麼INSERT和SELECT的行爲不同。爲什麼SELECT「看到」較新的表並插入「看到」較舊的表? –
嗯,這是一個很好的問題,我無法回答(我很抱歉,我在回答您的文章時沒有完全閱讀它)。它可能應該指向更有能力的團隊,即那些瞭解SQL Server內部運行方式的人。我將嘗試在不同版本的SQL Server上運行相同的示例並查看它的行爲。你使用哪個版本? – GSazheniuk
「您無法訪問第二個程序中創建的表格。」這是不正確的。臨時表有種動態範圍。它們沒有像變量那樣作用域。一旦創建了表,其他過程就可以讀取和寫入。雖然讀取顯然是陰影。 –