简体   繁体   English

是否可以告诉 SSMS 不要检查 t-sql 脚本中是否存在列?

[英]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.我有一个 t-sql 脚本,它向表中添加一个新列,然后根据同一个表中的其他一些列用值填充这些列,最后删除一些列。 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.我有一个 if 子句来检查丢失的列是否存在,但是即使 if 子句中的代码没有运行,SSMS 仍然会抱怨并显示错误消息。 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.是的,没有动态 SQL 是可能的,但有一些笨拙的解决方法。 I would just use EXEC for this.我会为此使用EXEC

The behaviour in SQL 2000 is explained here SQL 2000 中的行为在这里解释

Erland Sommarskog mentions "once all tables in a query exist, SQL Server performs full checks on the query." Erland Sommarskog 提到“一旦查询中的所有表都存在,SQL Server 就会对查询进行全面检查”。

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

你为什么不使用临时表或变量表,将最后一列添加到声明中,然后你就不会有这个问题了?

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.此外,看起来你有正确的 GO,但我发现如果在检查添加列之后我错过了 GO,那么甚至无法重新打开脚本。

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.聚会有点晚了,但是当我尝试根据 SQL Server 的版本进行条件检查时,我遇到了同样的情况。 I took the EXEC route mentioned above.我采取了上面提到的 EXEC 路线。 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.在下面作为内联 T-SQL 的示例中,如果在没有可用列的 SQL Server 的早期版本上运行,针对 sys.tables 的 SELECT 将导致无效的列名。

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.为了解决这个问题,我将 SQL 放在一个变量中,并将它作为 INSERT INTO 的一部分 EXEC() 来填充一个表变量。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM