为什么向 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.PersNR
到 tblBana.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 ... 创建外键,这将允许违反外键的数据。
“ALTER TABLE tablename WITH NOCHECK ...”添加 FK 的选项——这个解决方案对我有用。
@ManyToMany(fetch = FetchType.EAGER, cascade = CascadeType.DETACH) @JoinTable(name = "tbUsuariosTipoOcorrencia", joinColumns = { @JoinColumn(name = "idUsuario") }, inverseJoinColumns = { @JoinColumn(name = "idTipoOcorrencia") })
,我通过数据库查询解决了这个问题:alter table tbUsuariosTipoOcorrencia WITH NOCHECK add constraint FKnbxg3ua7b8c5d53wps69q6jh foreign key (idUsuario) references tbUsuarios
从表中删除所有现有数据,然后在表之间建立关系。
在将外键添加到表之前,请执行以下操作
确保表必须为空或列数据应匹配。确保它不为空。如果表格包含不去设计和更改,请手动执行。 alter table 表 1 添加外键(列名)引用表 2(列名) alter table 表 1 alter column 列名属性不为空
我想,外键表中的列值应该与主键表的列值匹配。如果我们试图在两个表之间创建外键约束,其中一列内的值(将成为外键)与主键表的列值不同,那么它将抛出消息。
因此,始终建议只在主键表列中存在的外键列中插入那些值。
例如。如果主表列具有值 1、2、3,并且在外键列中插入的值不同,则不会执行查询,因为它期望值介于 1 和 3 之间。
尝试 DELETE
tblDomare.PersNR
中的当前数据。因为 tblDomare.PersNR
中的值与 tblBana.BanNR
中的任何值都不匹配。
当您在表 B 中定义引用表 A 的主键的外键时,这意味着当值在 B 中时,它必须在 A 中。这是为了防止对表的不一致修改。
在您的示例中,您的表包含:
带有 PRIMARY KEY (PersNR)
的 tblDomare:
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
上有对应关系。您的错误是因为您在 tblDomare
中插入了行,而在 tblBana
中没有对应关系。
2个解决您的问题的解决方案:
要么在 tblBana 中添加带有 BanNR 的行(6811034679、7606091347、8508284163)
或删除 tblDomare 中与 tblBana 没有对应关系的所有行(但您的表将为空)
一般建议:您应该在填充表之前有外键约束。外键在这里是为了防止表的用户填写不一致的表。
用非常简单的话来说,您的表中已经存在数据,并且您尝试与之创建关系的表确实为已经存在的值设置了该主键。
要么删除现有表的所有值。在新表中添加所有外键引用的值。
我也遇到了这个错误,因为 Smutje 引用了确保您的基本外键表的外键列中没有不在参考表中的值,即(基本外键表中的每个值(列的值是外键)也必须在您的参考表列中)最好先清空基本外键表然后设置外键
您输入的数据表(tbldomare)与您分配的主键表数据不匹配。在 tbldomare 之间写入并添加这个词(不带检查)然后执行你的代码。
例如你输入了一个表 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);
Smutje 是正确的,Chad HedgeCock 提供了一个伟大的外行的例子。我想以乍得的例子为基础,提供一种查找/删除这些记录的方法。我们将使用 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 为空 注意右下角的行数。
去验证你要删除这些行的任何人!
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.PersNR
到 tblBana.BanNR
处具有相同数量的数据并进行虎钳。
在我的场景中,使用 EF,在尝试在现有数据上创建这个新的外键时,我错误地尝试在创建外键后填充数据(创建链接)。
解决方法是在创建外键之前填充您的数据,因为它会检查所有外键以查看链接是否确实有效。所以如果你还没有填充它,它就不可能工作。
我在我的项目中遇到了一些问题。
https://i.stack.imgur.com/gN6US.png
在子表中,没有任何记录 ID 等于 1 和 11
https://i.stack.imgur.com/GVrU3.png
我插入了 ID 等于 1 和 11 的 DEAL_ITEM_THIRD_PARTY_PO 表,然后我可以创建 FK
请先从该表中删除数据,然后再次运行迁移。你会获得成功
我有同样的问题。我的问题是 nullable: true in column (migration file):
AddColumn("dbo.table", "column", c => c.Int(nullable: true));
可能的解决方案:
将可为空的“假”更改为“真”。 (不推荐)将属性类型从 int 更改为 int? (推荐的)
如果需要,稍后在添加列 > 然后在以前的记录中缺少字段数据后进行更改
如果您已将现有属性从可空更改为不可空: 3) 填写数据库记录中的列数据
子表中的外键约束必须有一个带有主键的父表。主键必须是唯一的。外键值必须与专利表主键中的值匹配
当您将表列从可为空的列更改为该列是外键的不可为空的列时,您必须:
首先,用值初始化该列(因为它是不可为空的外键)。之后,您可以正常更改表格列。
请尝试以下查询:
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
仅供参考,以防您进行所有数据引用检查并且没有发现错误数据……显然,不可能在两个表和字段之间创建外键约束,其中这些字段是两个表中的主键!不要问我是怎么知道的。
INSERT INTO tblDomare (PersNR,fNamn,eNamn,Erfarenhet) Values (8508284163,'Johanna','Backman',1);
之前,必须在 tblBana 中插入相应的条目:INSERT INTO tblBana (BanNR) Values (8508284163);