繁体   English   中英

ALTER TABLE 语句与 FOREIGN KEY 约束冲突

[英]The ALTER TABLE statement conflicted with the FOREIGN KEY constraint

为什么向tblDomare表添加外键会导致此错误?

ALTER TABLE 语句与 FOREIGN KEY 约束“FK__tblDomare__PersN__5F7E2DAC”冲突。 冲突发生在数据库“almu0004”、表“dbo.tblBana”、“BanNR”列中。

代码

CREATE TABLE tblDomare
(PersNR VARCHAR (15) NOT NULL,
fNamn VARCHAR (15) NOT NULL,
eNamn VARCHAR (20) NOT NULL,
Erfarenhet VARCHAR (5),
PRIMARY KEY (PersNR));

INSERT INTO tblDomare (PersNR,fNamn,eNamn,Erfarenhet)
Values (6811034679,'Bengt','Carlberg',10);

INSERT INTO tblDomare (PersNR,fNamn,eNamn,Erfarenhet)
Values (7606091347,'Josefin','Backman',4);

INSERT INTO tblDomare (PersNR,fNamn,eNamn,Erfarenhet)
Values (8508284163,'Johanna','Backman',1);

CREATE TABLE tblBana
(BanNR VARCHAR (15) NOT NULL,
PRIMARY KEY (BanNR));

INSERT INTO tblBana (BanNR)
Values (1);

INSERT INTO tblBana (BanNR)
Values (2);

INSERT INTO tblBana (BanNR)
Values (3);

ALTER TABLE tblDomare
ADD FOREIGN KEY (PersNR)
REFERENCES tblBana(BanNR);

发生这种情况是因为您尝试创建从tblDomare.PersNRtblBana.BanNR的外键,但是/和tblDomare.PersNR中的值与tblBana.BanNR任何值都不匹配。 您不能创建违反参照完整性的关系。

这个查询对我非常有用。 它显示没有任何匹配项的所有值

select FK_column from FK_table
WHERE FK_column NOT IN
(SELECT PK_column from PK_table)

试试这个解决方案:

您的表中有一个数据项,其关联值在您要用作主键表的表中不存在。 使您的表为空或将关联的值添加到第二个表中。

可以使用 ALTER TABLE tablename WITH NOCHECK ... 创建外键,这将允许违反外键的数据。

添加 FK 的“ALTER TABLE tablename WITH NOCHECK ...”选项——这个解决方案对我有用。

我猜,外键表中的列值应该与主键表的列值匹配。 如果我们试图在两个表之间创建外键约束,其中一列(将成为外键)内的值与主键表的列值不同,那么它将抛出消息。

因此,始终建议仅在外键列中插入存在于主键表列中的那些值。

例如。 如果主表列的值为 1、2、3,并且在外键列中插入的值不同,则不会执行查询,因为它期望值介于 1 和 3 之间。

在向表中添加外键之前,请执行以下操作

  1. 确保表必须为空或列数据应匹配。
  2. 确保它不为空。
  3. 如果表包含不要去设计和更改,请手动进行。

    alter table 表 1 添加外键(列名)引用表 2(列名)

    更改表表 1 更改列列名称属性不为空

从表中清除数据,然后在它们之间建立关系。

尝试从tblDomare.PersNR DELETE当前数据。 因为tblDomare.PersNR中的值与tblBana.BanNR任何值都不匹配。

当您在表 B 中定义引用表 A 主键的外键时,这意味着当值在 B 中时,它必须在 A 中。这是为了防止对表的不一致修​​改。

在您的示例中,您的表包含:

tblDomare 与PRIMARY KEY (PersNR)

PersNR     |fNamn     |eNamn      |Erfarenhet
-----------|----------|-----------|----------
6811034679 |'Bengt'   |'Carlberg' |10
7606091347 |'Josefin' |'Backman'  |4
8508284163 |'Johanna' |'Backman'  |1
---------------------------------------------

tblBana:

BanNR
-----
1
2
3
-----

这个说法:

ALTER TABLE tblDomare
ADD FOREIGN KEY (PersNR)
REFERENCES tblBana(BanNR);

表示tblDomare中任何带有键PersNR必须在表tblBana中的键BanNR上具有对应BanNR 您的错误是因为您在tblDomare插入了行,而在tblDomare中没有对应tblBana

2 解决您的问题的解决方案

  • tblBana添加带有 BanNR 的行 (6811034679, 7606091347, 8508284163)
  • 或删除tblDomare中所有在tblDomare中没有对应关系的tblBana (但你的表会是空的)

一般建议:在填充表之前,您应该具有外键约束。 外键在这里是为了防止表的用户填充不一致的表。

我也有这个错误,因为 Smutje reffered 确保你的基本外键表的外键列中没有你的参考表中没有的值,即(你的基本外键表中的每个值(一个列的值是外键)也必须在您的参考表列中)最好先清空基本外键表然后设置外键

Smutje 是正确的,Chad HedgeCock 提供了一个很好的外行例子。 我想以 Chad 的示例为基础,提供一种查找/删除这些记录的方法。 我们将使用 Customer 作为父项,将 Order 作为子项。 CustomerId 是公共字段。

select * from Order Child 
left join Customer Parent on Child.CustomerId = Parent.CustomerId
where Parent.CustomerId is null 

如果你正在阅读这个线程......你会得到结果。 这些是孤儿。 select * from Order Child left join Customer Parent on Child.CustomerId = Parent.CustomerId where Parent.CustomerId is null 注意右下角的行数。

与您需要的任何人确认您将删除这些行!

begin tran 
delete Order
from Order Child 
left join Customer Parent on Child.CustomerId = Parent.CustomerId
where Parent.CustomerId is null 

运行第一个位。 检查行数 = 您的预期

提交 tran

commit tran 

当心。 有人草率的编程让你陷入了困境。 在删除孤儿之前,请确保您了解原因。 也许父级需要恢复。

您输入表 (tbldomare) 的数据与您已分配主键表的数据不匹配。 在 tbldomare 之间写入并添加这个词(使用 nocheck)然后执行您的代码。

例如你输入了一个表 tbldomar 这个数据

INSERT INTO tblDomare (PersNR,fNamn,eNamn,Erfarenhet)
Values (6811034679,'Bengt','Carlberg',10);

并且您分配了一个foreign key表以仅接受1,2,3

您有两种解决方案,一种是删除您输入表中的数据,然后执行代码。 另一个是写这个词(没有检查)把它放在你的表名之间并像这样添加

ALTER TABLE  tblDomare with nocheck
ADD FOREIGN KEY (PersNR)
REFERENCES tblBana(BanNR);

这发生在我身上,因为我正在设计我的数据库,我注意到我改变了主表上的种子,现在关系表在主表上没有外键。

所以我需要截断两个表,现在它可以工作了!

您应该查看表中的行是否有任何数据。 如果“是”,那么您应该截断表,否则您可以使它们在tblDomare.PersNRtblBana.BanNR和虎钳诗中具有相同数量的数据。

在我的场景中,使用 EF,在尝试在现有数据上创建这个新外键时,我错误地尝试在创建外键后填充数据(创建链接)。

解决方法是在创建外键之前填充您的数据,因为它会检查所有这些以查看链接是否确实有效。 所以如果你还没有填充它,它不可能工作。

请先从该表中删除数据,然后再次运行迁移。 你会获得成功

我在我的项目中遇到了一些问题。

在此处输入图片说明

在子表中,没有任何记录 Id 等于 1 和 11

法师

我插入了 ID 等于 1 和 11 的 DEAL_ITEM_THIRD_PARTY_PO 表,然后我可以创建 FK

从我们的角度来看,这是场景:

  1. 我们在数据库中有一个包含记录的现有表。
  2. 然后我引入了一个不可为空的外键
  3. 执行更新后,我收到此错误。

你问我怎么解决的?

解决方案:我刚刚删除了表的所有记录,然后尝试更新数据库并成功。

我有同样的问题。 我的问题是在列(迁移文件)中有nullable: true

AddColumn("dbo.table", "column", c => c.Int(nullable: true));
        

可能的解决方案:

  1. 将可为空的“假”更改为“真”。 (不建议)
  2. 将属性类型从int更改为int? (受到推崇的)

如果需要,稍后在添加列后更改此设置 > 然后在以前的记录中丢失字段数据

如果您已将现有属性从可为空更改为不可为空:
3) 填写数据库记录中的列数据

子表中的外键约束必须有一个带主键的父表。 主键必须是唯一的。 外键值必须匹配专利表主键中的值

当您将表列从可为空的列更改为不可为空的列时,该列是外键,您必须:

  1. 首先,用值初始化此列(因为它是外键不可为空)。

  2. 之后,您可以正常更改表格列。

我很简单的话,您的表中已经存在数据,并且您尝试与之建立关系的表确实为已经存在的值设置了主键

  1. 要么删除现有表的所有值。
  2. 在新表中添加外键引用的所有值。

请尝试以下查询:

CREATE TABLE tblBana
(BanNR VARCHAR (15) NOT NULL PRIMARY KEY,

);

CREATE TABLE tblDomare
(PersNR VARCHAR (15) NOT NULL PRIMARY KEY,
fNamn VARCHAR (15) NOT NULL,
eNamn VARCHAR (20) NOT NULL,
Erfarenhet VARCHAR (5),
FK_tblBana_Id VARCHAR (15) references  tblBana (BanNR)
);


INSERT INTO tblBana (BanNR)
Values (3);


INSERT INTO tblDomare (PersNR,fNamn,eNamn,Erfarenhet,FK_tblBana_Id)
Values (8508284173,'Johanna','Backman',1,3);

或者你可以使用这个

SELECT  fk_id FROM dbo.tableA
Except
SELECT fk_id From dbo.tableB

仅供参考,如果您进行了所有数据引用检查并没有发现错误数据……显然不可能在两个表和字段之间创建外键约束,其中这些字段是两个表中的主键! 不要问我是怎么知道的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM