为什么在使用 temp table 两次时会出现无效列名错误?

Why do I get an invalid column name error when using a temp table twice?

如果我 运行 将这些批次中的每一个分开,它就可以工作。但是,如果将它们合并到一个脚本中(就像 DACPAC 脚本 运行s 时所做的那样,或者将它们都放在 SSMS 中的一个选项卡中),我会在第二次插入时收到 Invalid column name 错误。这是为什么?如果我需要在一个脚本中使用这些 运行,我是否需要为第二批临时文件使用不同的名称 table?还是我遗漏了一些允许我使用相同名称的东西?

IF OBJECT_ID('tempdb..#source') IS NOT NULL DROP TABLE #source
SELECT FirstName, LastName INTO #source FROM Musician WHERE 1 = 0; -- set up temp table schema
INSERT INTO #source ( FirstName, LastName )
VALUES
('Geddy', 'Lee'),
('Alex', 'Lifeson') 

SELECT * FROM #source

GO

IF OBJECT_ID('tempdb..#source') IS NOT NULL DROP TABLE #source
SELECT [Name], Genre INTO #source FROM Band WHERE 1 = 0; -- set up temp table schema
INSERT INTO #source ( [Name], Genre )
VALUES
('Rush', 'Rock'),
('Ratt', 'Rock') 

SELECT * FROM #source

GO

在删除两个块中的表后使用 go 就可以解决问题。

IF OBJECT_ID('tempdb..#source') IS NOT NULL DROP TABLE #source
go
SELECT FirstName, LastName INTO #source FROM Musician WHERE 1 = 0; -- set up temp table schema
INSERT INTO #source ( FirstName, LastName )
VALUES
('Geddy', 'Lee'),
('Alex', 'Lifeson') 

SELECT * FROM #source

GO

IF OBJECT_ID('tempdb..#source') IS NOT NULL DROP TABLE #source
go
SELECT [Name], Genre INTO #source FROM Band WHERE 1 = 0; -- set up temp table schema
INSERT INTO #source ( [Name], Genre )
VALUES
('Rush', 'Rock'),
('Ratt', 'Rock') 

SELECT * FROM #source

GO

每批都是独立解析的。所以当你使用 GO 时它会起作用,因为它们在不同的批次中。

当您将所有内容放在同一批中时,SQL 服务器会解析它所看到的内容,并且它对隐藏在 IF 条件后面的 DROP 命令这样的逻辑视而不见。尝试以下操作,您会发现相同的结果:

IF (1=0) DROP TABLE IF EXISTS #x; CREATE TABLE #x(i int);
IF (1=1) DROP TABLE IF EXISTS #x; CREATE TABLE #x(j date);

你我都知道其中只有一个会 执行 ,但解析器会在执行(或评估)之前发现冗余的 table 名称任何条件)。

这是可行的,因为现在每个批次都是单独解析的:

IF (1=0) DROP TABLE IF EXISTS #x; CREATE TABLE #x(i int);
GO
IF (1=1) DROP TABLE IF EXISTS #x; CREATE TABLE #x(j date);

这实际上会 失败 即使它通过了解析(高亮和 select Parse 而不是 Execute),所以失明双向:

IF (1=0) DROP TABLE IF EXISTS #x; CREATE TABLE #x(i int);
GO
IF (1=1) CREATE TABLE #x(j date);