如何检查SQL Server表中是否存在列?

How to check if a column exists in a SQL Server table?

如果不存在,我需要添加一个特定的列。我有如下的东西,但它总是返回错误:

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

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


SQL Server 2005之后的版本:

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

马丁·史密斯的版本较短:

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

更简洁的版本

1
2
3
4
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的第一个参数表名可以是一个、两个或三个部分组成的名称格式。

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

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

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


根据您的具体要求调整以下内容:

1
2
3
4
5
6
7
8
if not exists (select
                     column_name
               from
                     INFORMATION_SCHEMA.columns
               where
                     table_name = 'MyTable'
                     and column_name = 'MyColumn')
    alter table MyTable add MyColumn int

编辑来处理编辑到问题:这应该有效-仔细检查代码是否有愚蠢的错误;例如,您在应用插入的同一数据库上查询信息模式吗?在这两条语句中,您的表/列名称是否有错别字?


试试这个…

1
2
3
4
5
6
7
8
9
10
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


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


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

1
2
3
4
SELECT *
  FROM INFORMATION_SCHEMA.COLUMNS
 WHERE TABLE_NAME = 'yourTableName'
 ORDER BY ORDINAL_POSITION

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


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

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

尝试以下方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
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

然后这样使用:

1
2
3
4
5
6
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,但不知道为什么。


对于检查列是否存在的人来说,删除它。

在SQL Server 2016中,可以使用新的die语句,而不是大的IF包装器

1
ALTER TABLE Table_name DROP COLUMN IF EXISTS Column_name


1
2
3
4
5
6
7
8
9
10
11
12
13
14
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

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

你可以在这里亲眼看到

1
2
3
4
5
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


这在SQL 2000中对我很有用:

1
2
3
4
5
6
7
8
9
10
IF EXISTS
(
    SELECT *
    FROM INFORMATION_SCHEMA.COLUMNS
    WHERE table_name = 'table_name'
    AND column_name = 'column_name'
)
BEGIN
...
END

试试这个

1
2
3
4
5
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')


我需要类似的SQL Server 2000,正如@mitch指出的,这只在2005+中有效。

如果它能帮助其他人,这就是我最终的工作:

1
2
3
4
5
6
7
8
if exists (
    select *
    from
        sysobjects, syscolumns
    where
        sysobjects.id = syscolumns.id
        and sysobjects.name = 'table'
        and syscolumns.name = 'column')


1
2
3
4
5
6
7
8
9
10
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

1
2
3
4
5
6
7
8
9
IF NOT EXISTS( SELECT NULL
            FROM INFORMATION_SCHEMA.COLUMNS
           WHERE table_name = 'tablename'
             AND table_schema = 'db_name'
             AND column_name = 'columnname')  THEN

  ALTER TABLE `TableName` ADD `ColumnName` int(1) NOT NULL default '0';

END IF;


接受答案的临时表版本:

1
2
3
4
5
6
7
if (exists(select 1
             from tempdb.sys.columns  
            where Name = 'columnName'
              and Object_ID = object_id('tempdb..#tableName')))
begin
...
end


1
2
3
select distinct object_name(sc.id)
from syscolumns sc,sysobjects so  
where sc.name like '%col_name%' and so.type='U'

麦氏的答案是好的,但假设在任何模式或数据库中没有任何相同的表名/列名对。为了使它在这种情况下安全,使用这个…

1
2
3
4
5
6
select *
from Information_Schema.Columns
where Table_Catalog = 'DatabaseName'
  and Table_Schema = 'SchemaName'
  and Table_Name = 'TableName'
  and Column_Name = 'ColumnName'


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

1
2
 sys.objects
 sys.columns

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

另外,无需使用SELECT *,只需使用NULL value进行测试即可。

1
2
3
4
5
6
7
IF EXISTS(
           SELECT NULL
           FROM INFORMATION_SCHEMA.COLUMNS
           WHERE
             TABLE_NAME = 'myTableName'
             AND COLUMN_NAME = 'myColumnName'
         )


下面是一个简单的脚本,用于管理数据库中列的添加:

1
2
3
4
5
6
7
8
9
10
11
12
13
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


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

1
2
3
4
5
6
7
8
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

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

1
2
3
4
5
6
7
8
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

还有另一个变种…

1
2
3
4
5
6
7
SELECT
  Count(*) AS existFlag
FROM
  sys.columns
WHERE
  [name] = N 'ColumnName'
  AND [object_id] = OBJECT_ID(N 'TableName')


1
2
3
IF EXISTS(SELECT 1 FROM sys.columns
      WHERE Name = N'columnName'
      AND Object_ID = Object_ID(N'schemaName.tableName'))

This should be the fairly easier way and straight forward solution to this problem. I have used this multiple times for similar scenarios. It works like a charm, no doubts on that.