我试着去谷歌,但是找不到方法
我有一个t-sql脚本,它向表中添加一个新列,然后根据同一个表中的其他一些列填充该列,最后删除一些列。一切正常。
当我想再次运行脚本时出现问题。我有一个if子句检查丢失的列是否存在,但SSMS仍然会抱怨并显示错误消息,即使if子句中的代码未运行。该脚本必须能够运行一次以上,并且我不希望显示错误消息!
在代码中(显然是测试代码,不想在这里转储生产代码......):
create table test (
Name text,
Switch int,
ValueA int,
ValueB int)
go
insert into test values ('Name', 0, 5, 10)
if not exists (select 1 from INFORMATION_SCHEMA.COLUMNS
where COLUMN_NAME = 'ValueC' and TABLE_NAME = 'test')
begin
alter table test
add ValueC int
end
go
-- This batch rasies error when run more then once!
if exists (select 1 from INFORMATION_SCHEMA.COLUMNS
where COLUMN_NAME = 'ValueA' and TABLE_NAME = 'test')
begin
update test
set ValueC = (select case Switch
when 0 then (select (ValueA - ValueB))
when 1 then (select (ValueB - ValueA))
end)
end
go
if exists (select 1 from INFORMATION_SCHEMA.COLUMNS
where COLUMN_NAME = 'ValueA' and TABLE_NAME = 'test')
begin
alter table test drop column ValueA
end
go
select * from test
--Name 0 10 -5
以下是错误消息:
Msg 207, Level 16, State 1, Line 6
Invalid column name 'ValueA'.
Msg 207, Level 16, State 1, Line 7
Invalid column name 'ValueA'.
干杯 --Jocke
答案 0 :(得分:2)
是的,没有动态SQL,但有一些kludgey解决方法是可能的。我只想使用EXEC
。
SQL 2000中的行为is explained here
Erland Sommarskog提到“一旦查询中存在所有表,SQL Server就会对查询执行全面检查。”
因此,通过在查询中将无操作引用添加到不存在的表中,可以延迟编译。通过此调整,下面的脚本可以多次运行而不会出现错误。
insert into test values ('Name', 0, 5, 10)
if not exists (select 1 from INFORMATION_SCHEMA.COLUMNS
where COLUMN_NAME = 'ValueC' and TABLE_NAME = 'test')
begin
alter table test
add ValueC int
end
go
create table #dummy
(i int)
-- This batch raised error when run more then once!
if exists (select 1 from INFORMATION_SCHEMA.COLUMNS
where COLUMN_NAME = 'ValueA' and TABLE_NAME = 'test')
begin
update test
set ValueC = (select case Switch
when 0 then (select (ValueA - ValueB))
when 1 then (select (ValueB - ValueA))
end) where not exists(select * from #dummy)
end
drop table #dummy
go
if exists (select 1 from INFORMATION_SCHEMA.COLUMNS
where COLUMN_NAME = 'ValueA' and TABLE_NAME = 'test')
begin
alter table test drop column ValueA
end
go
select * from test
--Name 0 10 -5
答案 1 :(得分:0)
为什么不直接使用临时表或变量表,将最后一列添加到声明中,然后你就不会遇到这个问题?
答案 2 :(得分:0)
我有这个确切的问题,唯一对我有用的是保存脚本。关闭它。然后再次打开它并在查询窗口中运行它。
此外,看起来你有正确的GO,但我发现如果我在检查后错过了GO来添加列,那么甚至不能重新打开脚本。