开发者

Is it possible to tell SSMS not to check if a column exists in a t-sql script?

I tried to google it, but din't find a way

I have a t-sql script that adds a new column to a table, then fills that columns with values depending on some other columns in the same table and finally removes some columns. This all works fine.

The problem occures when I want to run the script again. I have a if clause that checks if the missing columns exists, but SSMS still complains and displays error messaged even though the code inside the if clause if not run. The script must be able to run more then once, and I don't want the error messages to be displayed!

In code (obviously test code, don't want to dump production code here...):

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

Here is the error message:

Msg 207, Level 16, State 1, Line 6
Invalid column name 'ValueA'.
Msg 207, Level 16, State 1, Line 7
Invalid column name 'ValueA'.

Cheers --Jocke


Yes it is possible without dynamic SQL but with a bit of a kludgey workaround. I would just use EXEC for this.

The behaviour in SQL 2000 is explained here

Erland Sommarskog mentions "once all tables in a query exist, SQL Server performs full checks on the query."

So by adding a no-op reference in the query to a table that doesn't exist compilation can be deferred. With this adjustment the script below can be run multiple times without getting the error.

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


why don't you jsut use a temp table or variable table, add the last column to the declaration, and then you wouldn't have this problem?


I had this exact problem and the only thing that worked for me was to save the script. Close it. Then open it again in and run it in the query window.

Also, it looks like you have the proper GOs, but I found that if I was missing the GO after the check to add the column then not even re-opening the script worked.


Bit late to the party but I ran into this same scenario when trying to do conditional checks based on what version of SQL Server. I took the EXEC route mentioned above. In the below example as inline T-SQL, the SELECT against sys.tables would result in an invalid column name if ran on an earlier version of SQL Server that didn't have the column available.

To work around it, I put the SQL inside a variable and EXEC() it as part of a INSERT INTO to populate a table variable.

DECLARE @Status TABLE (
    Result bit
)
DECLARE @Result bit

    IF @SQLVer >= 11
        SET @SQL='SELECT 1 FROM sys.tables WHERE object_id=' + CONVERT(varchar,@CurrTableObjID) + ' AND is_filetable=1'
        DELETE FROM @Status
        INSERT INTO @Status
        EXEC (@SQL)
        SELECT @Result=Result FROM @Status
        IF IsNULL(@Result,0) = 1
        BEGIN
            PRINT 'Table ' + @CurrSchemaName + '.' + @CurrTableName + ' is a filetable'
            SET @BadTables=1
        END
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜