ALTER TABLE DROP COLUMN 失败,因为一个或多个对象访问此列

ALTER TABLE DROP COLUMN failed because one or more objects access this column

我正在尝试这样做:

ALTER TABLE CompanyTransactions DROP COLUMN Created

但我明白了:

Msg 5074, Level 16, State 1, Line 2 The object 'DF__CompanyTr__Creat__0CDAE408' is dependent on column 'Created'. Msg 4922, Level 16, State 9, Line 2 ALTER TABLE DROP COLUMN Created failed because one or more objects access this column.

这是第一个代码table。不知何故,迁移变得一团糟,我正在尝试手动回滚一些更改。

不知道这是什么:

DF__CompanyTr__Creat__0CDAE408

您必须先从该列中删除 constraints,然后才能删除该列。您引用的名称是 default constraint

例如

alter table CompanyTransactions drop constraint [df__CompanyTr__Creat__0cdae408];
alter table CompanyTransactions drop column [Created];

@SqlZim 的回答是正确的,但只是为了解释为什么会发生这种情况。我有过类似的问题,这是由非常无辜的事情引起的:将默认值添加到列

ALTER TABLE MySchema.MyTable ADD 
  MyColumn int DEFAULT NULL;

但是在 MS SQL 服务器领域,colum 上的默认值是一个 CONSTRAINT。就像每个约束一样,它有一个标识符。如果列在 CONSTRAINT 中使用,则不能删除该列。

所以你实际上可以做的是避免这类问题总是给你的默认约束一个显式名称,例如:

ALTER TABLE MySchema.MyTable ADD 
  MyColumn int NULL,
  CONSTRAINT DF_MyTable_MyColumn DEFAULT NULL FOR MyColumn;

您仍然需要在删除列之前删除约束,但是您至少预先知道它的名称

如答案中所述,您需要删除与您尝试删除的所有列相关的约束(由 sql 自动创建)。

执行以下步骤以完成必要的工作。

  1. 使用系统存储过程实用程序 sp_helpconstraint 获取所有约束的名称 - 按照 exec sp_helpconstraint '<your table name>'
  2. 执行
  3. 获得约束名称后,复制该约束名称并执行下一条语句,即 alter table <your_table_name> drop constraint <constraint_name_that_you_copied_in_1>(仅类似于此或类似格式)
  4. 删除约束后,您可以使用常规方法删除 1 个或多个列,即 Alter table <YourTableName> Drop column column1, column2

当您更改列 datatype 时,您需要为每个数据库更改 constraint key

  alter table CompanyTransactions drop constraint [df__CompanyTr__Creat__0cdae408];

您需要做几件事:

  1. 您首先需要检查信息模式中是否存在约束
  2. 则需要加入sys.default_constraints和sys.columns进行查询 如果列和 default_constraints 具有相同的对象 ID
  3. 当您在步骤 2 中加入时,您将从 default_constraints 中获取约束名称。你放弃了那个约束。这是我做的一个这样的例子。
-- 1. Remove constraint and drop column
IF EXISTS(SELECT *
          FROM INFORMATION_SCHEMA.COLUMNS
          WHERE TABLE_NAME = N'TABLE_NAME'
            AND COLUMN_NAME = N'LOWER_LIMIT')
   BEGIN
    DECLARE @sql NVARCHAR(MAX)
    WHILE 1=1
        BEGIN
            SELECT TOP 1 @sql = N'alter table [TABLE_NAME] drop constraint ['+dc.name+N']'
            FROM sys.default_constraints dc
            JOIN sys.columns c
            ON c.default_object_id = dc.object_id
            WHERE dc.parent_object_id = OBJECT_ID('[TABLE_NAME]') AND c.name = N'LOWER_LIMIT'
            IF @@ROWCOUNT = 0
                BEGIN
                    PRINT 'DELETED Constraint on column LOWER_LIMIT'
                    BREAK
                END
        EXEC (@sql)
    END;
    ALTER TABLE TABLE_NAME DROP COLUMN LOWER_LIMIT;
    PRINT 'DELETED column LOWER_LIMIT'
   END
ELSE
   PRINT 'Column LOWER_LIMIT does not exist'
GO

除了已接受的答案外,如果您使用 Entity Migrations 更新数据库,则应在 Up() 函数的开头添加此行迁移文件:

Sql("alter table dbo.CompanyTransactions drop constraint [df__CompanyTr__Creat__0cdae408];");

您可以在以 FK_dbo.

开头的 nuget 数据包管理器控制台的错误中找到约束名称

我遇到了同样的问题,这是对我有用的脚本 table,名称由两部分组成,用句点“.”分隔。

使用 [数据库名称] 走 更改 TABLE [TableNamePart1].[TableNamePart2] 删除约束 [DF__ TableNamePart1D__ColumnName__5AEE82B9] 走 ALTER TABLE [TableNamePart1].[ TableNamePart1] DROP COLUMN [ColumnName] 开始

我需要用 Guid 替换 INT 主键。在几次失败的尝试之后,下面的 EF 代码对我有用。如果您急于设置默认值...您最终会得到一个单一的 Guid 作为现有记录的键。

protected override void Up(MigrationBuilder migrationBuilder)
        {
            migrationBuilder.DropUniqueConstraint("PK_Payments", "Payments");

            migrationBuilder.DropColumn(
                name: "PaymentId",
                table: "Payments");

            migrationBuilder.AddColumn<Guid>(
                name: "PaymentId",
                table: "Payments",
                type: "uniqueidentifier",
                defaultValueSql: "NewId()",
                nullable: false);
}

从错误消息中复制默认约束名称,并按照与要删除的列相同的方式键入。