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

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

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


当前回答

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

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

其他回答

您可以使用信息模式系统视图来查找有关您感兴趣的表的任何信息:

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

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

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

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

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

 sys.objects
 sys.columns

甚至可以使用一些其他访问方法来检查系统目录。

此外,无需使用SELECT*,只需通过NULL值测试即可

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

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

尝试以下操作:

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,但我不知道为什么不这样做。