【问题标题】:How to check if a column exists in a SQL Server table?如何检查 SQL Server 表中是否存在列?
【发布时间】:2010-09-13 01:54:26
【问题描述】:

如果特定列不存在,我需要添加它。我有类似以下的内容,但它总是返回 false:

IF EXISTS(SELECT *
          FROM   INFORMATION_SCHEMA.COLUMNS
          WHERE  TABLE_NAME = 'myTableName'
                 AND COLUMN_NAME = 'myColumnName') 

如何检查 SQL Server 数据库的表中是否存在列?

【问题讨论】:

  • 我实际上并不认为问题中的代码有任何问题:在 2008 R2 中对我来说效果很好。 (也许您在错误的数据库中运行它?也许您的数据库区分大小写,而您的 myTableName / myColumnName 字符串中的大小写不正确?这种类型的查询似乎比 COL_LENGTH 解决方案更灵活:我可以通过适当地为“INFORMATION_SCHEMA”添加前缀来针对不同的数据库甚至通过数据库链接运行它。无法使用 COL_LENGTH 元数据函数来执行此操作。
  • @mwardm - COL_LENGTH('AdventureWorks2012.HumanResources.Department ','ModifiedDate') 工作正常。
  • 相关小提示:如果您想在添加列后立即更新列(我相信很多用户都为此目的搜索此文章),您可以使用EXEC sp_executesql 和形成的UPDATE 语句。
  • 真正的答案是你应该添加你正在检查的数据库,所以它是FROM [YourDatabase].INFORMATION_SCHEMA.COLUMNS
  • 你也可以很简单的使用syscolumns和sysobjects。

标签: sql-server sql-server-2008 tsql sql-server-2012 sql-server-2016


【解决方案1】:

SQL Server 2005 及以上版本:

IF EXISTS(SELECT 1 FROM sys.columns 
          WHERE Name = N'columnName'
          AND Object_ID = Object_ID(N'schemaName.tableName'))
BEGIN
    -- Column Exists
END

Martin Smith 的版本较短:

IF COL_LENGTH('schemaName.tableName', 'columnName') IS NOT NULL
BEGIN
    -- Column Exists
END

【讨论】:

  • 在 Martin Smith 的版本中,要提到的一件事是不要将 columnName 包含在方括号 [ ] 中。当 columnName 在方括号 [ ] 内时,即使该列存在于表中,它也会给出 null
  • @HemendraSinghChauhan - 这是因为它们不是名称的一部分。与sys.columns中的名字比较时你也会发现
  • @MartinSmith 不知道,我正在使用您的答案并遇到了这个问题。通常我在添加列时使用方括号,所以我也在 COL_LENGTH 函数中使用它们。我的代码是这样的:Alter table Table_Name Add [ColumnName] NVarchar(max) NULL; Select COL_LENGTH('[TABLE_NAME]', '[COLUMN_NAME]')
  • 是的,这是无效的。 COL_LENGTH 的参数需要不加引号。理论上,有人可以创建一个实际上名称为 [COLUMN_NAME] 的列 - 例如CREATE TABLE #T([[COLUMN_NAME]]] INT); SELECT * FROM #T 如果这不是规则,那将是模棱两可的。
  • 当字段 id varchar(max) = null 时,较短的版本不工作
【解决方案2】:

更简洁的版本

IF COL_LENGTH('table_name','column_name') IS NULL
BEGIN
/* Column does not exist or caller does not have permission to view the object */
END

关于查看元数据的权限这一点适用于所有答案,而不仅仅是这个。

请注意,COL_LENGTH 的第一个参数表名称可以根据需要采用一个、两个或三个部分名称格式。

引用不同数据库中的表的示例是

COL_LENGTH('AdventureWorks2012.HumanResources.Department','ModifiedDate')

与使用元数据视图相比,此答案的一个区别是元数据函数(如 COL_LENGTH)始终只返回有关已提交更改的数据,而不管有效的隔离级别如何。

【讨论】:

  • 这比其他一些答案可读性差,这可能是为什么它的评价不高。
  • @Bill - 以什么方式可读性降低?在 Firefox 中看起来不错。这个答案比接受的答案晚了 2 年多,这解释了 IMO 的评级。如果您的意思不太清楚它是否存在,请检查这种类型的习语在 SQL Server 中很常见。例如使用IF OBJECT_ID('TableName','U') IS NULL 检查对象是否存在或使用DB_ID('foo') 检查数据库是否存在。
  • @MartinSmith 我敢肯定他的意思是可读性较差,因为如果您不知道这个习语,并且您从其他人那里继承了此代码,您将不会立即理解代码的作用。有点像用 C++ 编写 x>>2 而不是 x/4。更冗长的代码 (if exists (select column_name from information_schema ...)) 占用更多空间,但没有人会挠头试图弄清楚它的作用。
  • 除了更简洁之外,这是一种更快的解决方案。访问INFORMATION_SCHEMA 视图或sys.columns 会命中磁盘,而COL_LENGTH 使用缓存的数据库元数据。
  • 这可能不是评价最高的答案,因为它是在另一个答案之后 2.5 年给出的。这就是为什么我在比较两个答案的评分时总是检查日期。克服更早给出的答案需要更长的时间。 ;)
【解决方案3】:

调整以下内容以满足您的特定要求:

if not exists (select
                     column_name
               from
                     INFORMATION_SCHEMA.columns
               where
                     table_name = 'MyTable'
                     and column_name = 'MyColumn')
    alter table MyTable add MyColumn int

编辑以处理对问题的编辑:这应该可行 - 仔细检查您的代码是否存在愚蠢的错误;例如,您是否在与您的插入应用相同的数据库上查询 INFORMATION_SCHEMA?您在任一语句中的表/列名称中是否有错字?

【讨论】:

  • 我刚刚发现在 where 子句之后添加 TABLE_SCHEMA = 'mySchema' 可以解决问题。
  • -1:不回答 OP 的问题,只添加有关如何添加新列的新信息,尽管 OP 根本没有询问,不解决 OP 的评论。
  • +1 完美地回答了 OP 的问题,并获得了 OP 下一步想要获取的额外信息。这就是我一直在寻找的。​​span>
【解决方案4】:

试试这个...

IF NOT EXISTS(
  SELECT TOP 1 1
  FROM INFORMATION_SCHEMA.COLUMNS
  WHERE 
    [TABLE_NAME] = 'Employees'
    AND [COLUMN_NAME] = 'EmployeeID')
BEGIN
  ALTER TABLE [Employees]
    ADD [EmployeeID] INT NULL
END

【讨论】:

  • 此方法也适用于 SQL CE,而提到的其他一些方法则不适用。
  • 您可以使用SELECT 1 代替SELECT TOP 1 1 ;)。
  • EXISTS 语句中,SQL 会自动优化列(很像count(*)),所以SELECT * 就足够了。
  • 为了完整起见,您应该考虑在 WHERE 子句中添加and [TABLE_SCHEMA] = '???'
【解决方案5】:

对于在删除列之前检查列存在的人。

SQL Server 2016 开始,您可以使用新的 DIE 语句代替大的 IF 包装器

ALTER TABLE Table_name DROP COLUMN IF EXISTS Column_name

【讨论】:

    【解决方案6】:

    我更喜欢INFORMATION_SCHEMA.COLUMNS 而不是系统表,因为 Microsoft 不保证在版本之间保留系统表。例如,dbo.syscolumns 在 SQL 2008 中仍然有效,但它已被弃用,将来可能随时被删除。

    【讨论】:

    • 嗯,是的,这是不言而喻的,因为INFORMATION_SCHEMA 视图只包含 ANSI 标准的元数据。但是,这对于存在性测试来说已经足够了。
    • 微软表示“在 SQL Server 的未来版本中,微软可能会通过在列列表的末尾添加列来扩充任何系统目录视图的定义。我们建议不要使用语法 SELECT * FROM sys。生产代码中的目录视图名称,因为返回的列数可能会改变并破坏您的应用程序。”这意味着他们不会删除列或更改其顺序。这对于除边缘情况外的所有情况都足够好的向后兼容性。
    【解决方案7】:

    您可以使用信息架构系统视图来查找有关您感兴趣的表的几乎所有信息:

    SELECT *
      FROM INFORMATION_SCHEMA.COLUMNS
     WHERE TABLE_NAME = 'yourTableName'
     ORDER BY ORDINAL_POSITION
    

    您还可以使用 Information_schema 视图查询视图、存储过程以及有关数据库的几乎所有内容。

    【讨论】:

    • 这正是问卷所使用的,如果它不存在,他需要知道如何添加该列。
    【解决方案8】:

    尝试类似:

    CREATE FUNCTION ColumnExists(@TableName varchar(100), @ColumnName varchar(100))
    RETURNS varchar(1) AS
    BEGIN
    DECLARE @Result varchar(1);
    IF EXISTS (SELECT * FROM INFORMATION_SCHEMA.Columns WHERE TABLE_NAME = @TableName AND COLUMN_NAME = @ColumnName)
    BEGIN
        SET @Result = 'T'
    END
    ELSE
    BEGIN
        SET @Result = 'F'
    END
    RETURN @Result;
    END
    GO
    
    GRANT EXECUTE ON  [ColumnExists] TO [whoever]
    GO
    

    然后像这样使用它:

    IF ColumnExists('xxx', 'yyyy') = 'F'
    BEGIN
      ALTER TABLE xxx
      ADD yyyyy varChar(10) NOT NULL
    END
    GO
    

    它应该适用于 SQL Server 2000 和 SQL Server 2005。不确定 SQL Server 2008,但不明白为什么不。

    【讨论】:

      【解决方案9】:

      首先检查table/column(id/name) 组合是否存在于dbo.syscolumns(包含字段定义的内部SQL Server 表)中,如果不存在则发出适当的ALTER TABLE查询以添加它。例如:

      IF NOT EXISTS ( SELECT  *
                  FROM    syscolumns
                  WHERE   id = OBJECT_ID('Client')
                          AND name = 'Name' ) 
      ALTER TABLE Client
      ADD Name VARCHAR(64) NULL
      

      【讨论】:

        【解决方案10】:

        我的一位好朋友和同事向我展示了如何在 SQL SERVER 2005+ 中使用带有 SQL 函数 OBJECT_IDCOLUMNPROPERTYIF 块来检查列。您可以使用类似于以下内容的内容:

        You can see for yourself here

        IF (OBJECT_ID(N'[dbo].[myTable]') IS NOT NULL AND
            COLUMNPROPERTY( OBJECT_ID(N'[dbo].[myTable]'), 'ThisColumnDoesNotExist', 'ColumnId') IS NULL)
        BEGIN
            SELECT 'Column does not exist -- You can add TSQL to add the column here'
        END
        

        【讨论】:

        • 当然,如果您确信该表存在,您可以省略条件的第一部分并仅检查COLUMNPROPERTY
        【解决方案11】:
        declare @myColumn   as nvarchar(128)
        set @myColumn = 'myColumn'
        if not exists (
            select  1
            from    information_schema.columns columns 
            where   columns.table_catalog   = 'myDatabase'
                and columns.table_schema    = 'mySchema' 
                and columns.table_name      = 'myTable' 
                and columns.column_name     = @myColumn
            )
        begin
            exec('alter table myDatabase.mySchema.myTable add'
            +'    ['+@myColumn+'] bigint       null')
        end
        

        【讨论】:

          【解决方案12】:

          这在 SQL 2000 中对我有用:

          IF EXISTS 
          (
              SELECT * 
              FROM INFORMATION_SCHEMA.COLUMNS 
              WHERE table_name = 'table_name' 
              AND column_name = 'column_name'
          )
          BEGIN
          ...
          END
          

          【讨论】:

            【解决方案13】:

            试试这个

            SELECT COLUMNS.*
            FROM   INFORMATION_SCHEMA.COLUMNS COLUMNS,
                   INFORMATION_SCHEMA.TABLES TABLES
            WHERE  COLUMNS.TABLE_NAME = TABLES.TABLE_NAME
                   AND Upper(COLUMNS.COLUMN_NAME) = Upper('column_name') 
            

            【讨论】:

            • 您不需要 INFORMATION_SCHEMA.TABLES 并且您不过滤特定表的列,因此它有时会为不同表中的相同列名返回多行;)。
            【解决方案14】:

            我需要类似的 SQL SERVER 2000,正如@Mitch 指出的那样,这仅适用于 2005+。

            如果它可以帮助其他人,这最终对我有用:

            if exists (
                select * 
                from 
                    sysobjects, syscolumns 
                where 
                    sysobjects.id = syscolumns.id 
                    and sysobjects.name = 'table' 
                    and syscolumns.name = 'column')
            

            【讨论】:

              【解决方案15】:
              if exists (
                select * 
                from INFORMATION_SCHEMA.COLUMNS 
                where TABLE_NAME = '<table_name>' 
                and COLUMN_NAME = '<column_name>'
              ) begin
                print 'Column you have specified exists'
              end else begin
                print 'Column does not exist'
              end
              

              【讨论】:

                【解决方案16】:
                IF NOT EXISTS( SELECT NULL
                            FROM INFORMATION_SCHEMA.COLUMNS
                           WHERE table_name = 'TableName'
                             AND table_schema = 'SchemaName'
                             AND column_name = 'ColumnName')  BEGIN
                
                  ALTER TABLE [SchemaName].[TableName] ADD [ColumnName] int(1) NOT NULL default '0';
                
                END;
                

                【讨论】:

                • 我认为您的意思是 table_schema='schema_name'。
                【解决方案17】:

                accepted answer 的临时表版本:

                if (exists(select 1 
                             from tempdb.sys.columns  
                            where Name = 'columnName'
                              and Object_ID = object_id('tempdb..#tableName')))
                begin
                ...
                end
                

                【讨论】:

                • 这与接受的答案有何不同?临时表在接受的答案中不起作用吗?
                • 正确。接受的答案不适用于临时表,因为“sys.columns”必须指定为“tempdb.sys.columns”,并且表名必须以“tempdb..”开头。
                【解决方案18】:
                select distinct object_name(sc.id)
                from syscolumns sc,sysobjects so  
                where sc.name like '%col_name%' and so.type='U'
                

                【讨论】:

                  【解决方案19】:

                  Wheat 的回答很好,但假设您在任何架构或数据库中都没有任何相同的表名/列名对。为了确保该条件的安全,请使用此...

                  select *
                  from Information_Schema.Columns
                  where Table_Catalog = 'DatabaseName'
                    and Table_Schema = 'SchemaName'
                    and Table_Name = 'TableName'
                    and Column_Name = 'ColumnName'
                  

                  【讨论】:

                    【解决方案20】:

                    有几种方法可以检查列是否存在。 我强烈建议使用INFORMATION_SCHEMA.COLUMNS,因为它是为了与用户交流而创建的。 请考虑以下表格:

                     sys.objects
                     sys.columns
                    

                    甚至还有其他一些可用于检查system catalog.的访问方法

                    另外,不用SELECT *,直接用NULL value测试一下

                    IF EXISTS(
                               SELECT NULL 
                               FROM INFORMATION_SCHEMA.COLUMNS
                               WHERE
                                 TABLE_NAME = 'myTableName'
                                 AND COLUMN_NAME = 'myColumnName'
                             ) 
                    

                    【讨论】:

                    • 不管你SELECT *EXISTS,因为当exists被使用时它并没有真正选择所有的行和所有的列,在内部它只是检查存在而不是实际检查所有行和列
                    【解决方案21】:

                    最简单易懂的解决方案之一是:

                    IF COL_LENGTH('Table_Name','Column_Name') IS NULL
                     BEGIN
                        -- Column Not Exists, implement your logic
                     END 
                    ELSE
                     BEGIN
                        -- Column Exists, implement your logic
                     END
                    

                    【讨论】:

                      【解决方案22】:

                      这是我用来管理在数据库中添加列的简单脚本:

                      IF NOT EXISTS (
                              SELECT *
                              FROM sys.Columns
                              WHERE Name = N'QbId'
                                  AND Object_Id = Object_Id(N'Driver')
                              )
                      BEGIN
                          ALTER TABLE Driver ADD QbId NVARCHAR(20) NULL
                      END
                      ELSE
                      BEGIN
                          PRINT 'QbId is already added on Driver'
                      END
                      

                      在本例中,Name 是要添加的 ColumnNameObject_IdTableName

                      【讨论】:

                        【解决方案23】:

                        如果列不存在,请执行以下操作:

                        BEGIN
                            IF (COL_LENGTH('[dbo].[Table]', 'Column ') IS NULL)
                            BEGIN
                                //Do something
                            END
                        END;
                        

                        如果列存在则做某事:

                        BEGIN
                            IF (COL_LENGTH('[dbo].[Table]', 'Column ') IS NOT NULL)
                            BEGIN
                                //Do something
                            END
                        END;
                        

                        【讨论】:

                          【解决方案24】:

                          以下查询可用于检查表中是否存在搜索列。我们也可以根据搜索结果做出决定,如下所示。

                          IF EXISTS (SELECT 'Y' FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = <YourTableName> AND COLUMN_NAME = <YourColumnName>)
                            BEGIN
                              SELECT 'Column Already Exists.'
                            END
                            ELSE
                            BEGIN
                              ALTER TABLE <YourTableName> ADD <YourColumnName> <DataType>[Size]
                            END
                          

                          【讨论】:

                            【解决方案25】:
                            //Only checks
                            IF EXISTS (
                            SELECT *
                            FROM INFORMATION_SCHEMA.COLUMNS
                            WHERE TABLE_CATALOG = 'Database_Name'
                            and TABLE_SCHEMA = 'Schema_Name'
                            and TABLE_NAME = 'Table_Name'
                            and COLUMN_NAME = 'Column_Name'
                            and DATA_TYPE = 'Column_Type') -- Where statement lines can be deleted.
                            
                            BEGIN
                            --COLUMN EXISTS IN TABLE
                            END
                            
                            ELSE BEGIN
                            --COLUMN DOES NOT EXISTS IN TABLE
                            END
                            

                            【讨论】:

                              【解决方案26】:

                              又一个变种...

                              SELECT 
                                Count(*) AS existFlag 
                              FROM 
                                sys.columns 
                              WHERE 
                                [name] = N 'ColumnName' 
                                AND [object_id] = OBJECT_ID(N 'TableName')
                              

                              【讨论】:

                                【解决方案27】:

                                另一个贡献是以下示例,如果不存在则添加列。

                                    USE [Northwind]
                                    GO
                                
                                    IF NOT EXISTS(SELECT * FROM INFORMATION_SCHEMA.COLUMNS 
                                                    WHERE TABLE_NAME = 'Categories'
                                                        AND COLUMN_NAME = 'Note')
                                    BEGIN
                                
                                    ALTER TABLE Categories ADD Note NVARCHAR(800) NULL
                                
                                    END
                                    GO
                                

                                希望对您有所帮助。 西蒙娜

                                【讨论】:

                                  【解决方案28】:

                                  table -->script table as -->new windows - 你有设计脚本。 在新窗口中检查并查找列名

                                  【讨论】:

                                    【解决方案29】:

                                    执行以下查询以检查给定表中是否存在该列:

                                    IF(SELECT COLUMN_NAME from INFORMATION_SCHEMA.COLUMNS where TABLE_NAME = 'TableName' AND COLUMN_NAME = 'ColumnName') IS NOT NULL
                                    PRINT 'Column Exists in the given table';
                                    

                                    【讨论】:

                                      【解决方案30】:
                                      IF EXISTS (
                                      SELECT *
                                      FROM INFORMATION_SCHEMA.COLUMNS
                                      WHERE TABLE_CATALOG = 'Database Name'
                                      and TABLE_SCHEMA = 'Schema Name'
                                      and TABLE_NAME = 'Table Name'
                                      and COLUMN_NAME = 'Column Name'
                                      and DATA_TYPE = 'Column Type') -- Where statement lines can be deleted.
                                      
                                      BEGIN
                                      --COLUMN EXISTS IN TABLE
                                      END
                                      
                                      ELSE BEGIN
                                      --COLUMN DOES NOT EXISTS IN TABLE
                                      END
                                      

                                      【讨论】:

                                        猜你喜欢
                                        • 2010-09-18
                                        • 2010-09-15
                                        • 2016-03-06
                                        • 1970-01-01
                                        • 1970-01-01
                                        相关资源
                                        最近更新 更多