Yul*_*idy 5 sql sql-server stored-procedures temp-tables
我正在尝试更改在存储过程中创建并填充的现有临时表,在我正在执行这些更改时调用此表.我无法更改调用存储过程,我需要将列添加到临时表,所以我尝试了这个:
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;
Run Code Online (Sandbox Code Playgroud)
它编译,但当我运行它我得到:
消息207,级别16,状态1,过程ProcName,行#
无效列名称'Column1'
看起来这个代码甚至没有被执行.
有人可以告诉我这是否可能以及如何?
谢谢.
您显然可以这样做,但您不能在更改它的同一范围内插入更改后的临时表。不要问我为什么。
您可以在第二个 proc 中使用动态 sql 来获得较低的嵌套级别,或者调用另一个 proc。像这样:
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
Run Code Online (Sandbox Code Playgroud)
正如大卫布朗在上面的回答中提到的,这也可以通过使用动态 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)
Run Code Online (Sandbox Code Playgroud)
如果将Alter 和Update 放在同一个执行中,它将不起作用,它们不能同时执行,否则与静态代码相同的问题再次出现。这种方式就像模拟对另一个存储过程的额外调用,但没有额外的过程。