子行を追加または更新できません:外部キー制約が失敗します


174

表1

+----------+-------------+------+-----+---------+----------------+
| Field    | Type        | Null | Key | Default | Extra          |
+----------+-------------+------+-----+---------+----------------+
| UserID   | int(11)     | NO   | PRI | NULL    | auto_increment |
| Password | varchar(20) | NO   |     |         |                |
| Username | varchar(25) | NO   |     |         |                |
| Email    | varchar(60) | NO   |     |         |                |
+----------+-------------+------+-----+---------+----------------+

テーブル2

+------------------+--------------+------+-----+---------+----------------+
| Field            | Type         | Null | Key | Default | Extra          |
+------------------+--------------+------+-----+---------+----------------+
| UserID           | int(11)      | NO   | MUL |         |                |
| PostID           | int(11)      | NO   | PRI | NULL    | auto_increment |
| Title            | varchar(50)  | NO   |     |         |                |
| Summary          | varchar(500) | NO   |     |         |                |
+------------------+--------------+------+-----+---------+----------------+

エラー:

com.mysql.jdbc.exceptions.MySQLIntegrityConstraintViolationException: 
Cannot add or update a child row: a foreign key constraint fails 
(`myapp/table2`, CONSTRAINT `table2_ibfk_1` FOREIGN KEY (`UserID`) 
REFERENCES `table1` (`UserID`)) 

何が悪いのですか?私は読むhttp://www.w3schools.com/Sql/sql_foreignkey.asp、何が問題なのかわかりません。


4
エラーをトリガーするクエリを投稿できますか?
ダンプ

38
簡単に言えば、にtable2.UserID存在しないの値を挿入または更新しようとしていtable1.UserIDます。
ジョーステファネッリ

理由は不明ですが、データベースをWindows環境からLinuxに移動した後、リレーションを削除して再作成する必要がありました(そのときに問題に気づきました)。値は存在しましたが、関係を削除して再度追加することで修正されました。あなたは明らかにそうすることをかなり注意深くする必要があるかもしれません。
johnsnails 2015

回答:


235

現在に格納されている値に基づいて、フィールドにtable2有効な値がない行を追加または更新しようとしたため、このエラーが発生しています。さらにいくつかのコードを投稿した場合は、特定の原因を診断するのに役立ちます。UserIDtable1


PreparedStatement st = connection.prepareStatement( "table2に挿入(UserID、PostID、Title、Summary)" + "values(UserID、?、?、?)");
トム

15
反対投票の目的がわからない。私の答えは完全に有効で正しいです。
Brian Driscoll、2011

うーん...準備されたステートメントで名前付きパラメーターと名前なしパラメーターを混在させることは間違いなく良い考えではありません。実行ステートメントで指定されたUserIDの適切な値を持つ「値(?、?、?、?)」である必要があります。
Brian Driscoll、2011

したがって、table1からユーザーIDを取得するには、別のSQLステートメントを実行する必要がありますか?
トム

5
ほとんどの場合0、それが事実である場合はNullに置き換えます
Jeffrey NicholsonCarré2013年

123

それはあなたがに挿入しようとしていることを意味して存在しない値。table2UserIDtable1


104

単純なハックは、テーブルで操作を実行する前に外部キーチェックを無効にすることです。単に問い合わせる

SET FOREIGN_KEY_CHECKS=0

これにより、他のテーブルに対する外部キーのマッチングが無効になります。テーブルを使い終わったら、もう一度有効にします

SET FOREIGN_KEY_CHECKS=1

これは私にとって何度もうまくいきます。


これをどのように使用しますか?
Sachin、プネ

2
@SachinfromPuneはSET FOREIGN_KEY_CHECKS = 0を追加するだけです。mysqlファイルの開始時およびSET FOREIGN_KEY_CHECKS = 1; mysqlファイルの最後で、データを再インポートする
inrsaurabh

1
これは問題ありませんか?参照整合性が失われますよね?
roadrunner66

参照整合性は、正しいインデックスエントリの存在によってサポートされます。キーとインデックスが正しい限り、一括入力中にキーチェックを無効にできるはずです。
バーノンキーナン

46

別の奇妙なケースを発見しました:InnoDBテーブルからMyISAMテーブルに誤って外部キーを作成した場合、データが他の方法で有効であっても、MySQLは挿入時にこのエラーをスローします。

http://nick.zoic.org/art/mysql-foreign-key-error/を参照してください


1
はい、同じ問題があります。2つのテーブルはInnoDBでなければなりません!
emeraldhieu 2015

2
ヒントをありがとう、私は同じ問題を抱えていました。これは、MyISAMからInnoDBにテーブルを変換する方法に関するMySQLドキュメントへのリンクです dev.mysql.com/doc/refman/5.7/en/…TLDR:ALTER TABLE table_name ENGINE = InnoDB;
Guilherme Vaz 2017

実際、これは私のデータベースの場合でした。MyISAMエンジンをInnoDBに変更することにしました。最後に、思い通りにデータベースを操作できます。
Mike

17

table2.UserID存在しない値intがあるため、このエラーが発生しますtable1.UserIDtable2.UserIDこの外部キーを作成する前に手動で値を設定したと思います)。
このシーンの1つの例:table1.UserID値1、2、3をtable2.UserID取得し、値4 を取得します(手動で追加)。あなたが外部キーを作るときに、彼らは見つけることができないUserID = 4からtable1、エラーがocurseます。
このエラーを修正するには、から削除UserID = 4するtable2か、両方を空にしてから外部キーを作成します。
幸運を!


11

これを理解するには少し時間がかかりました。簡単に言うと、他のテーブルを参照するテーブルにはすでにデータがあり、その値の1つ以上が親テーブルに存在しません。

たとえば、Table2には次のデータがあります。

UserID    PostID    Title    Summary
5         1         Lorem    Ipsum dolor sit

表1

UserID    Password    Username    Email
9         ********    JohnDoe     john@example.com

Table2を変更して外部キーを追加しようとすると、UserID = 5がTable1に存在しないため、クエリは失敗します。


10

テーブル2で外部キーを作成する前にテーブル1に行を挿入した場合、自動インクリメント値はテーブル1で2、テーブル2で1であるため、外部キー制約エラーが発生します。これを解決するには、テーブル1を切り捨て、自動増分値を1に戻します。次に、テーブル2を追加できます。


10

MyISAMでは外部キーとトランザクションがサポートされていないため、データベースエンジンがInnoDBに設定されていることを確認してください


2
ALTER TABLE my_table ENGINE = InnoDB;
Bishwas Mishra

7

少しだけ修正します 。JoinColumnをTable1で「nullable = true」、Table2で「UserID」フィールドを「insertable = false」と「nullable = true」にします。

Table1エンティティ:

@OneToMany(targetEntity=Table2.class, cascade = CascadeType.ALL)
@JoinColumn(name = "UserID", referencedColumnName = "UserID", nullable = true)
private List<Table2> table2List;

Table2エンティティ:

@Column(insertable = false, nullable = true)
private int UserID;

この答えは私の問題を完全に解決しました、これを共有してくれてありがとう 私のキーは、子オブジェクト/テーブルの前のキーとして使用しているフィールドに@Column(insertable = false、nullable = true)を追加することでした。
イスラエルの

6

私は同じ問題を抱えていましたが、解決策は簡単です。

親テーブルに存在ない IDを子テーブルに追加しようとしています。

InnoDBには、値を追加せずにauto_incrementカラムを増やすことがあるバグがあるため、よく確認してください。たとえば、 INSERT ... ON DUPLICATE KEY


本気?存在しないID参照を挿入しないでください...チェックするだけ
Blaztix

5

同様の問題がありました。コンテンツがあり、列がnullにできないテーブルに外部キーを適用しようとしています。2つのオプションがあります。

  1. 外部キー制約を適用する列をNULL可能にします。そうすれば、一部のフィールドがnullにできることを知って、外部キーが適用されます。(これは私がやったことです。
  2. 外部キー制約を適用する列を作成し、外部キーを列に挿入するクエリを記述して、外部キー制約を適用します。(これは試しませんでしたが、うまくいくはずです

4

外部キーに挿入する値が親テーブルに存在することを確認してください。それは私を助けました。たとえば、に挿入user_id = 2したtable.2table.1がないuser_id = 2場合、制約はエラーをスローします。私のものは正確にはエラーコード#1452でした。これが同じ問題を持つ他の人を助けることを願っています!


3

同じ問題があり、その理由は、外部キーを追加する前に最初のテーブルに行があったためです。


1

私も同じ問題に直面し、問題は私の親テーブルエントリの値が外部キーテーブルの値と一致しないことでした。すべての行をクリアしてからお試しください。


この制約では、Table2で参照されるユーザーがTable1で既に定義されている必要があります。
ソラック

1

他の人から提供された解決策が機能しなかった場合。次に、親テーブルと子テーブルのデータベースエンジンを確認してみてください。私の場合、親テーブルのエンジンを「MyISAM」に設定し、InnoDBに変更して修正しました。

これが私のように立ち往生している他の人を助けることを願っています。


1

データベースのカスケードに対してondeleteフィールドを配置しないでください。

したがって、onDeleteフィールドをRESTRICTに設定します

頑張ってね♥


0

このエラーを引き起こしたさらに別の奇妙なケース。私は外部キーをid主キーに誤って参照していました。これは、誤ったテーブル変更コマンドが原因でした。これは、INFORMATION_SCHEMAテーブルをクエリすることでわかりました(このstackoverflowの回答を参照してください)。

テーブルが非常に混乱していたため、ALTER TABLEコマンドで修正できませんでした。ようやくテーブルを削除して再構築しました。これにより、integrityErrorが取り除かれました。


0

おそらく、userID列を追加している間に、特定のテーブルのデータが確立されているため、デフォルト値は0になります。NOT NULL


0

「子行を追加または更新できません:外部キー制約が失敗しました」というエラーも発生しました。親テーブルに新しい行を追加するときにエラーが発生しました

問題は、外部キー制約が子テーブルではなく親テーブルで定義されていたことでした。


0

mysqlインデックスまたはテーブル間の関係を使用する場合は、最初に列(たとえば、city_id)を削除し、同じ名前(たとえば、:city_id)で新しい列を作成します。次に、再試行してください...


0

テーブルに含まれている既存のデータはありますか?その場合は、外部キーを追加するテーブルのすべてのデータを消去してみてください。次に、コードを実行(外部キーを追加)します。

この問題に何度も遭遇しました。これは、既存のテーブルに外部キーを追加する場合に、テーブル内のすべてのデータをクリアすることで機能します。

これがうまくいくことを願っています:)


0

table2のUserIDフィールドのインデックスを削除します。私にとってのスーツ


-1

子テーブルの外部キー制約が失敗しています

この問題は、次の理由により発生する可能性があります。

Spring mvcでそれを実行している場合、mysqlがIDのタイプを認識できないことがあるので、IDタイプを明示的に記述する必要があります。したがって、エンティティクラスの両方のテーブルのように明示的に設定します@GeneratedValue (strategy = GenerationType.IDENTITY)

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.