【问题标题】:The ALTER TABLE statement conflicted with the FOREIGN KEY constraintALTER TABLE 语句与 FOREIGN KEY 约束冲突
【发布时间】:2014-03-17 08:28:04
【问题描述】:

为什么在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);

【问题讨论】:

    标签: sql sql-server database foreign-keys


    【解决方案1】:

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

    【讨论】:

    • 这对我来说是答案,但我仍然很难意识到问题出在哪里,所以我将举一个外行的例子。如果您有一个名为“Orders”的表和一个名为“Customers”的表,并且您删除了一些旧客户,但没有删除他们的订单,如果您决定将外键从 Orders.CustomerId 设置为 Customers,您将收到此错误。ID。有些订单已经没有对应的客户了,所以无法添加外键。
    • 这是一个检查错误值的查询: select distinct referrerTable.referenceColumn from referrerTable left join referrerTable on referrerTable.referenceColumn = referrerTable.referenceColumn where referrerTable.referenceColumn is null;
    • 在紧要关头,您还可以使用“ALTER TABLE tablename WITH NOCHECK ...”选项来添加 FK。这将允许您添加关系,即使现有数据破坏了约束。首先清理数据显然更好,但这至少为您提供了另一种选择。
    • @DaveInMaine 如果有人“在需要时”停用数据库约束,我会问为什么一开始就用它们来麻烦自己,而不是在对数据库完整性不感兴趣的情况下简单地跳过它们。
    • @Sinjai 例如在执行INSERT INTO tblDomare (PersNR,fNamn,eNamn,Erfarenhet) Values (8508284163,'Johanna','Backman',1); 之前,必须在 tblBana 中插入相应的条目:INSERT INTO tblBana (BanNR) Values (8508284163);
    【解决方案2】:

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

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

    【讨论】:

    • 在尝试查找错误条目时非常简单且非常有用。非常感谢!
    【解决方案3】:

    试试这个解决方案:

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

    【讨论】:

      【解决方案4】:

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

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

      【讨论】:

      • 请注意,允许此类违规行为会破坏外键约束的目的。
      • 危险的...!!!仅当您不想丢失表中当前的数据时才应使用。但即便如此,为什么不进行备份,然后删除无效的 ID。
      • 我需要通过 java/spring/code 来实现,而不是直接通过 SQL 查询,任何想法如何使用以下代码来做到这一点:@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
      【解决方案5】:

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

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

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

      【讨论】:

        【解决方案6】:

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

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

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

          alter table 表1 alter column Column Name 属性不为空

        【讨论】:

          【解决方案7】:

          从表中删除所有现有数据,然后在表之间建立关系。

          【讨论】:

          • 谢谢,最大。如果他们有数据,它对我有用,即使关系是完美的,Update-Database 命令也不起作用。
          • 没有必要删除任何数据,只要它们根据正在创建的外键是有效的。
          • @ΩmegaMan 您正在此页面上进行编辑,没有添加任何内容,因此不应该进行。
          【解决方案8】:

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

          【讨论】:

          • @agenc 我回答你的问题了吗?
          【解决方案9】:

          当你在表 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 有对应关系。您的错误是因为您在 tblDomare 中插入了行,而在 tblBana 中没有对应关系。

          2 个解决方案来解决您的问题:

          • tblBana 中添加行,在 (6811034679、7606091347、8508284163) 中添加 BanNR
          • 或删除tblDomare 中与tblBana 没有对应关系的所有行(但您的表格将是空的)

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

          【讨论】:

          • "您的错误是因为您在 tblDomare 中插入了行,而在 tblBana 中没有对应关系。"就是这样!
          【解决方案10】:

          我也有这个错误 正如 Smutje 所引用的,确保您的基本外键表的外键列中没有不在参考表中的值,即(基本外键表中的每个值(作为外键的列的值)也必须在您的参考表列中) 最好先清空基本外键表然后设置外键

          【讨论】:

            【解决方案11】:

            Smutje 是正确的,Chad HedgeCock 提供了一个伟大的外行的例子。 我想以乍得的例子为基础,提供一种查找/删除这些记录的方法。 我们将使用 Customer 作为父级,使用 Order 作为子级。 CustomerId 是通用字段。

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

            如果您正在阅读此主题...您将获得结果。这些是孤儿。从订单子中选择 * 在 Child.CustomerId = Parent.CustomerId 上左加入客户父级 其中 Parent.CustomerId 为 null 请注意右下角的行数。

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

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

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

            提交翻译

            commit tran 
            

            小心。有人草率的编程让你陷入了这个混乱。在删除孤儿之前,请确保您了解原因。也许父母需要恢复。

            【讨论】:

            • 感谢您的回复。我正在使用 stackoverflow 数据库(实际上是 gamedev),当我与用户 LEFT JOIN 徽章时发现了两个 NULL。难怪约束不起作用......
            【解决方案12】:

            在我们看来,情况是这样的:

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

            我是怎么解决你的问题的?

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

            【讨论】:

              【解决方案13】:

              您输入的数据表(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);
              

              【讨论】:

                【解决方案14】:

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

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

                【讨论】:

                  【解决方案15】:

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

                  【讨论】:

                    【解决方案16】:

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

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

                    【讨论】:

                      【解决方案17】:

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

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

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

                      【讨论】:

                        【解决方案18】:

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

                        【讨论】:

                          【解决方案19】:

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

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

                          【讨论】:

                            【解决方案20】:

                            我遇到了同样的问题。 我的问题是 nullable: true 在列(迁移文件):

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

                            可能的解决方案:

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

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

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

                            【讨论】:

                              【解决方案21】:

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

                              【讨论】:

                                【解决方案22】:

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

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

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

                                【讨论】:

                                  【解决方案23】:

                                  请尝试以下查询:

                                  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);
                                  

                                  【讨论】:

                                    【解决方案24】:

                                    或者你可以使用这个

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

                                    【讨论】:

                                      【解决方案25】:

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

                                      【讨论】:

                                        猜你喜欢
                                        • 1970-01-01
                                        • 2014-01-19
                                        • 2014-09-08
                                        • 1970-01-01
                                        • 2023-03-06
                                        • 2017-06-29
                                        • 1970-01-01
                                        相关资源
                                        最近更新 更多