在 SQL 服务器的临时表中添加和更新后验列

Adding and updating columns a posteriori in temp tables in SQL Server

我正在尝试更改现有的临时文件 table,它是在调用此存储过程的存储过程中创建和填充的,我正在其中进行这些更改。我无法更改调用存储过程,我需要将列添加到临时 table,所以我尝试了这个:

ALTER TABLE #MyTemp 
ADD Column1 VARCHAR(100);           

UPDATE x
SET Column1 = a.SomeColumn
FROM #MyTemp x
INNER JOIN dbo.AnotherTable a (NOLOCK) ON a.ColumnName = x.ColumnName 
WHERE somecondition;

它可以编译,但是当我 运行 它时,我得到:

Msg 207, Level 16, State 1, Procedure ProcName, Line #
Invalid column name 'Column1'

看起来这段代码甚至没有被执行。

有人能告诉我这是否可行以及如何实现吗?

谢谢。

存储过程将具有与您在过程运行后尝试更新它时不同的作用域。您需要将 alter 语句放在 proc 中才能生效,或者将存储过程的内容带到存储过程之外,这样您的 temp table 将与您的更新语句共享相同的范围。

例如:

CREATE PROC SPX_TEST
AS
SELECT 1 AS ABC INTO #TEMP_A 


EXEC SPX_TEST
SELECT * FROM #TEMP_A

生成错误,指出临时 table 不存在。

你显然可以做到这一点,但你不能在你改变它的同一范围内插入改变的温度table。不要问我为什么。

您可以在第二个过程中使用动态 sql 来获得较低的嵌套级别,或调用另一个过程。像这样:

use tempdb
go

create or alter proc a
as
begin
  create table #t(id int)
  exec b
  select * from #t
end

go

create or alter proc b
as
begin
   alter table #t add a int

   exec c

end

go

create or alter proc c
as
begin
   insert into #t(id,a) values (1,1)

end

go

正如 David Browne 在他上面的回答中提到的,这也可以通过使用动态 sql 来实现,但是有一个问题,方法如下:

DECLARE @ColName1 NVARCHAR(100)
DECLARE @DynamicSQL NVARCHAR(500)

SET @ColName1='Column1'
SET @DynamicSQL = 'ALTER TABLE #MyTemp ADD ['+ CAST(@ColName1 AS NVARCHAR(100)) +'] 
NVARCHAR(100) NULL; '

EXEC(@DynamicSQL)

SET @DynamicSQL = 'UPDATE x SET '+ CAST(@ColName1 AS NVARCHAR(100)) + = a.SomeColumn
FROM #MyTemp x INNER JOIN dbo.AnotherTable a (NOLOCK) ON a.ColumnName = x.ColumnName 
WHERE somecondition;

EXEC(@DynamicSQL)

如果把Alter和Update放在同一个执行是不行的,它们不能同时执行,否则又是静态代码一样的问题。这种方式就像模拟对另一个存储过程的额外调用,但没有额外的过程。