这里内部重复的临时表的情况是:创建嵌套的存储过程
步骤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
“您无法访问第二个程序中创建的表格。”这是不正确的。临时表有种动态范围。它们没有像变量那样作用域。一旦创建了表,其他过程就可以读取和写入。虽然读取显然是阴影。 –