【问题标题】:Add a column to a table, if it does not already exist向表中添加列(如果该列尚不存在)
【发布时间】:2012-02-10 20:24:58
【问题描述】:

我想为 MS SQL Server 编写一个查询,将一列添加到表中。但是当我运行/执行以下查询时,我不希望显示任何错误。

我正在使用这种查询来添加一个表...

IF EXISTS (
       SELECT *
       FROM   sys.objects
       WHERE  OBJECT_ID = OBJECT_ID(N'[dbo].[Person]')
              AND TYPE IN (N'U')
   )

但我不知道如何为列编写此查询。

【问题讨论】:

  • 您应该使用sys.tables 而不是“通用”sys.objects - 这样您就不必明确指定类型(从sys.tables 已经很明显......)
  • COL_LENGTH Alternative 仅适用于 SQL-Server 2008,但它有效。
  • @MartinSmith 非常不重复。您的链接是解决它的一种可能方法(实际上,现在是推荐的方法)。但是问题实际上是不同的,并且可以使用其他解决方案(例如,如果 SQL 在 ADD COLUMN 语法中添加了 IF NOT EXISTS 子句)
  • @Brondahl - 自您回复的评论发布以来,这个问题在 8.5 年内一直存在,因此可能无需恐慌。目前,这里的所有答案基本上都是链接 Q 中的答案

标签: sql-server add not-exists


【解决方案1】:

您可以通过使用sys.columns 表io sys.objects 来使用类似的构造。

IF NOT EXISTS (
  SELECT * 
  FROM   sys.columns 
  WHERE  object_id = OBJECT_ID(N'[dbo].[Person]') 
         AND name = 'ColumnName'
)

【讨论】:

  • 请注意,在这种情况下,您希望在实际代码中使用 IF NOT EXISTS。
  • 对于优化查询,您可以使用 top 1 和 select 语句
  • @BanketeshvarNarayan 这是不正确的。 EXISTS 子句中子查询的执行计划是相同的。 SELECT 1SELECT TOP 1 之类的东西是不必要的。 EXISTS 子句本身告诉查询优化器至少在 SQL Server 中只执行评估 EXISTS... 所需的最少读取。其他数据库引擎可能具有或多或少高效的查询优化器。
  • @BanketeshvarNarayan 如果您正在优化您的 ADD Column 查询...您必须经常运行它们!
  • @user391339 - 我已经发布了与 OP 发布的类似的构造,但是是的,如果您想在列 不存在 存在的情况下采取行动,则声明将是 IF NOT存在。我真的觉得没有必要为此编辑答案,但如果您认为这是一种改进,请随时自行编辑。
【解决方案2】:
IF COL_LENGTH('table_name', 'column_name') IS NULL
BEGIN
    ALTER TABLE table_name
    ADD [column_name] INT
END

【讨论】:

  • 我试过这样做,但它返回一个错误,指出 COL_LENGTH 函数不存在。
  • 需要 SQL Server 2008+
  • 小添加 - 不应在列名中使用方括号,因为COL_LENGTH('table_name', '[column_name]') 在 SQL Server 2016 中总是返回 null (COL_LENGTH('[table_name]', 'column_name') works as expected)。
  • 那是因为如果你把括号放在单引号内,你实际上是在引用字符串两次。
【解决方案3】:

另一种选择。我更喜欢这种方法,因为它的写作较少,但两者完成了同样的事情。

IF COLUMNPROPERTY(OBJECT_ID('dbo.Person'), 'ColumnName', 'ColumnId') IS NULL
BEGIN
    ALTER TABLE Person 
    ADD ColumnName VARCHAR(MAX) NOT NULL
END

我还注意到您正在寻找表确实存在的位置,这显然就是这个

 if COLUMNPROPERTY( OBJECT_ID('dbo.Person'),'ColumnName','ColumnId') is not null

【讨论】:

  • 我喜欢。我认为在这里发帖最好的部分是找到这样的宝石。
  • 什么是'ColumnId'?
  • 'ColumnId' 是您要检查的列属性的名称。您可能已经使用了列上存在的任何属性名称,例如名称等。
【解决方案4】:

这是另一个对我有用的变体。

IF NOT EXISTS (SELECT 1
        FROM INFORMATION_SCHEMA.COLUMNS
        WHERE upper(TABLE_NAME) = 'TABLENAME'
        AND upper(COLUMN_NAME) = 'COLUMNNAME')
BEGIN
    ALTER TABLE [dbo].[Person] ADD Column
END
GO

编辑: 请注意,INFORMATION_SCHEMA 视图可能不会总是更新,请改用SYS.COLUMNS

IF NOT EXISTS (SELECT 1 FROM SYS.COLUMNS....

【讨论】:

  • 如果您要编辑,只需编辑它以使用 SYS.COLUMNS 而不是说明更改查询!
【解决方案5】:
IF NOT EXISTS (SELECT * FROM syscolumns
  WHERE ID=OBJECT_ID('[db].[Employee]') AND NAME='EmpName')
  ALTER TABLE [db].[Employee]
  ADD [EmpName] VARCHAR(10)
GO

我希望这会有所帮助。 More info

【讨论】:

【解决方案6】:
IF NOT EXISTS (SELECT 1  FROM SYS.COLUMNS WHERE  
OBJECT_ID = OBJECT_ID(N'[dbo].[Person]') AND name = 'DateOfBirth')
BEGIN
ALTER TABLE [dbo].[Person] ADD DateOfBirth DATETIME
END

【讨论】:

    【解决方案7】:

    当检查另一个数据库中的列时,您可以简单地包含数据库名称:

    IF NOT EXISTS (
      SELECT * 
      FROM   DatabaseName.sys.columns 
      WHERE  object_id = OBJECT_ID(N'[DatabaseName].[dbo].[TableName]') 
             AND name = 'ColumnName'
    )
    

    【讨论】:

      猜你喜欢
      • 2021-11-04
      • 1970-01-01
      • 1970-01-01
      • 2014-12-03
      • 2014-04-19
      • 2019-09-22
      • 1970-01-01
      • 2018-02-02
      • 2019-03-12
      相关资源
      最近更新 更多