ChatGPT解决这个技术问题 Extra ChatGPT

对象 'DF__*' 取决于列 '*' - 将 int 更改为 double

基本上,我在我的 EF 数据库中得到了一个具有以下属性的表:

public int Id { get; set; }
public string Title { get; set; }
public string Description { get; set; }
public string Image { get; set; }
public string WatchUrl { get; set; }
public int Year { get; set; }
public string Source { get; set; }
public int Duration { get; set; }
public int Rating { get; set; }
public virtual ICollection<Category> Categories { get; set; }

它工作正常,但是当我将 Rating 的 int 更改为 double 时,更新数据库时出现以下错误:

对象“DF_Movies_Rating__48CFD27E”取决于“评级”列。 ALTER TABLE ALTER COLUMN 评级失败,因为一个或多个对象访问此列。

有什么问题?

删除约束 DF_Movies_Rating__48CFD27E 然后更改字段的类型
@JoeTaras但我从未创建过名为那个的约束。它是什么,我在哪里可以找到它?
创建字段时,DBMS 会自动创建一个约束。如果你扩展你的表信息,你会在约束部分找到它。告诉我你是否能找到;)

S
Sᴀᴍ Onᴇᴌᴀ

尝试这个:

在更改字段类型之前删除约束 DF_Movies_Rating__48CFD27E。

约束通常由 DBMS (SQL Server) 自动创建。

要查看与表关联的约束,请在对象资源管理器中展开表属性,然后是约束类别,如下所示:

https://i.stack.imgur.com/fYfVn.png

您必须在更改字段类型之前删除约束。


@ManirajSS:ALTER TABLE yourtable DROP CONSTRAINT DF_Movies_Rating__48CFD27E
是什么触发了约束的创建?我有一堆,我真的不想要它们!
嗯,如果我想在那里使用我的框架(Laravel)和 dropColumn 的数据库迁移该怎么办?我不知道如何删除由 SQL 服务器自动生成的具有神秘名称的约束:(
我确定:我删除了它,文件夹 Constraints 变为空,当我运行应用程序或调用 update-database 时,它再次重新创建自己,我发布了这个问题:stackoverflow.com/questions/40267769/…
为什么 SQLServer 不隐式删除约束?毕竟,它确实隐含地创建了它!
h
h3adache

我将其添加为响应以解释约束来自何处。我试图在评论中做到这一点,但很难在那里很好地编辑:-/

如果您创建(或更改)具有默认值的列的表,它将为您创建约束。

例如,在您的表格中,它可能是:

CREATE TABLE Movie (
    ...
    rating INT NOT NULL default 100
)

它将为默认 100 创建约束。

如果你像这样创建它

CREATE TABLE Movie (
  name VARCHAR(255) NOT NULL,
  rating INT NOT NULL CONSTRAINT rating_default DEFAULT 100
);

然后,您将获得一个命名良好的约束,当您更改所述表时,该约束更易于引用。

ALTER TABLE Movie DROP CONSTRAINT rating_default;
ALTER TABLE Movie ALTER COLUMN rating DECIMAL(2) NOT NULL;
-- sets up a new default constraint with easy to remember name
ALTER TABLE Movie ADD CONSTRAINT rating_default DEFAULT ((1.0)) FOR rating;

您可以组合最后两条语句,以便在一行中更改列并命名约束(如果它是现有表,则必须这样做)


感谢您添加有关如何通过首先命名所有约束来避免该问题的信息。 (即避免丢弃随机命名约束的问题)
L
Luis Siquot

这是 tsql 方式

 ALTER TABLE yourtable DROP CONSTRAINT constraint_name     -- DF_Movies_Rating__48CFD27E

为了完整起见,这只是将@Joe Taras 的评论显示为答案


S
Slava Utesinov

由于约束具有不可预知的名称,您可以编写特殊脚本(DropConstraint)在不知道它的名称的情况下将其删除(在 EF 6.1.3 测试):

public override void Up()
{    
    DropConstraint();
    AlterColumn("dbo.MyTable", "Rating", c => c.Double(nullable: false));
}

private void DropConstraint()
{
    Sql(@"DECLARE @var0 nvarchar(128)
          SELECT @var0 = name
          FROM sys.default_constraints
          WHERE parent_object_id = object_id(N'dbo.MyTable')
          AND col_name(parent_object_id, parent_column_id) = 'Rating';
          IF @var0 IS NOT NULL
              EXECUTE('ALTER TABLE [dbo].[MyTable] DROP CONSTRAINT [' + @var0 + ']')");
}

public override void Down()
{            
    AlterColumn("dbo.MyTable", "Rating", c => c.Int(nullable: false));    
}

此答案在您无法对约束名称进行硬编码的基于迁移的环境中非常有效。
如果您为 AlterColumn 创建了一个包装器/扩展/重载函数 - 例如 AlterColumnX - 您可以在其中包含 DropConstraint 逻辑 - 您可以传入表名和列名,因此您不必再次编写它们。
A
AZ_

MS SQL Studio 会在您删除列时进行处理,但如果您需要以编程方式删除约束,这里是简单的解决方案

这是一个代码片段,它将删除具有默认约束的列:

DECLARE @ConstraintName nvarchar(200)
SELECT @ConstraintName = Name FROM SYS.DEFAULT_CONSTRAINTS WHERE PARENT_OBJECT_ID = OBJECT_ID('__TableName__') AND PARENT_COLUMN_ID = (SELECT column_id FROM sys.columns WHERE NAME = N'__ColumnName__' AND object_id = OBJECT_ID(N'__TableName__'))
IF @ConstraintName IS NOT NULL
EXEC('ALTER TABLE __TableName__ DROP CONSTRAINT ' + @ConstraintName)
IF EXISTS (SELECT * FROM syscolumns WHERE id=object_id('__TableName__') AND name='__ColumnName__')
EXEC('ALTER TABLE __TableName__ DROP COLUMN __ColumnName__')

只需将 TableName 和 ColumnName 替换为适当的值。即使列已被删除,您也可以安全地运行它。

奖励:这是删除外键和其他类型约束的代码。

IF EXISTS(SELECT 1 FROM INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE where TABLE_NAME = '__TableName__' AND COLUMN_NAME = '__ColumnName__')
BEGIN
SELECT @ConstraintName = CONSTRAINT_NAME FROM INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE where TABLE_NAME = '__TableName__' AND COLUMN_NAME = '__ColumnName__'
EXEC('ALTER TABLE __TableName__ DROP CONSTRAINT ' + @ConstraintName)
END

Blog


现在两次救了我的命。他们两个,都必须删除检查约束。首先,我必须使用第一个查询。其次,我必须使用第二个查询,因为在 SYS.DEFAULT_CONSTRAINTS 表中找不到检查约束。非常感谢!
S
Sᴀᴍ Onᴇᴌᴀ

当我们尝试删除依赖的列时,我们会看到这种错误:

对象 'DF__*' 依赖于列 ''。

删除依赖于该列的约束:

ALTER TABLE TableName DROP CONSTRAINT dependent_constraint;

例子:

消息 5074,级别 16,状态 1,第 1 行对象“DF__Employees__Colf__1273C1CD”依赖于列“Colf”。消息 4922,级别 16,状态 9,第 1 行 ALTER TABLE DROP COLUMN Colf 失败,因为一个或多个对象访问此列。

丢弃约束(DF__Employees__Colf__1273C1CD):

ALTER TABLE Employees DROP CONSTRAINT DF__Employees__Colf__1273C1CD;

然后你可以删除列:

Alter Table TableName Drop column ColumnName

C
Community

解决方案 :

打开数据库表 -> 展开表 -> 展开约束并看到这个

https://i.stack.imgur.com/N64WP.png


虽然此代码可能会回答问题,但提供有关此代码为何和/或如何回答问题的额外上下文可提高其长期价值。
K
Kirsten

我在尝试运行迁移以解决它时遇到此错误我重命名了列并使用重新生成了迁移

add-migration migrationname -force

在包管理器控制台中。然后我就可以跑了

update-database

成功地。


请注意,这不会重命名列 - 它会删除列并添加新列。除非您在迁移中添加自定义代码,否则您将丢失该列中曾经存在的所有数据。
S
Sheikh M. Haris

从多个表中删除列时,我遇到了以下默认约束错误。如果您需要更改列的数据类型,则会出现类似的问题。

对象“DF_TableName_ColumnName”依赖于列“ColumnName”。

要解决这个问题,我必须首先使用以下查询删除所有这些约束

DECLARE @sql NVARCHAR(max)=''     
SELECT @SQL += 'Alter table ' + Quotename(tbl.name) + '  DROP constraint ' + Quotename(cons.name) + ';'
 FROM SYS.DEFAULT_CONSTRAINTS cons 
 JOIN   SYS.COLUMNS col ON col.default_object_id = cons.object_id
 JOIN   SYS.TABLES tbl ON tbl.object_id = col.object_id
 WHERE  col.[name] IN ('Column1','Column2')

--PRINT @sql
EXEC Sp_executesql @sql 

之后,我删除了所有这些列(我的要求,此问题中未提及)

DECLARE @sql NVARCHAR(max)='' 
SELECT @SQL += 'Alter table ' + Quotename(table_catalog)+ '.' + Quotename(table_schema) + '.'+ Quotename(TABLE_NAME) 
               + '  DROP column ' + Quotename(column_name) + ';'
FROM   information_schema.columns where COLUMN_NAME IN ('Column1','Column2')  
--PRINT @sql
EXEC Sp_executesql @sql 

我在这里发布以防有人发现同样的问题。

快乐编码!


这段代码在哪里放弃约束?它会丢弃列,而且相当危险。另外,请注意 this answer 已经显示了一种生成所需 SQL 的方法。
@GertArnold您提到的答案是针对特定表的,而我的脚本是针对具有相似列名的多个表的。另外,我修改了答案并添加了约束部分。感谢提及。