20

これはよくある間違いのようですが、私の人生ではこれを理解することはできません。

MySQLに外部キーを介して結合された一連のInnoDBユーザーテーブルがあります。親userテーブル、および電子メールアドレスやアクションなどを格納する子テーブルのセット。これらはすべてuser、外部キーによって親テーブルに関連付けられておりuid、すべての親キーと子キーはint(10)です。

すべての子テーブルには、uidを指す外部キー制約を持つ値がありuser.uid、とに設定されON DELETE CASCADEますON UPDATE CASCADE

からユーザーを削除するuserと、子の制約付きエントリがすべて削除されます。ただし、値を更新しようとすると、子テーブルへの変更をuser.uidカスケードするのではなく、次のエラーが発生します。uid

#1452 - Cannot add or update a child row: a foreign key constraint fails (`accounts`.`user_email`, CONSTRAINT `user_email_ibfk_2` FOREIGN KEY (`uid`) REFERENCES `user` (`uid`) ON DELETE CASCADE ON UPDATE CASCADE)

ここで明らかな何かが欠けているに違いないと感じています。でキー制約を削除しuser_email、の値を更新しようとするとuser、同じエラーが発生しますが、次のアルファベットuserの子テーブルが発生するため、テーブル固有のエラーではないと思います。

編集:

からの結果を追加しますSHOW ENGINE INNODB STATUS

------------------------
LATEST FOREIGN KEY ERROR
------------------------
121018 22:35:41 Transaction:
TRANSACTION 0 5564387, ACTIVE 0 sec, process no 1619, OS thread id 2957499248 updating or deleting, thread declared inside InnoDB 499
mysql tables in use 1, locked 1
17 lock struct(s), heap size 2496, 9 row lock(s), undo log entries 2
MySQL thread id 3435659, query id 24068634 localhost root Updating
UPDATE `accounts`.`user` SET `uid` = '1' WHERE `user`.`uid` = 306
Foreign key constraint fails for table `accounts`.`user_email`:
,
  CONSTRAINT `user_email_ibfk_2` FOREIGN KEY (`uid`) REFERENCES `user` (`uid`) ON DELETE CASCADE ON UPDATE CASCADE
Trying to add in child table, in index `uid` tuple:
DATA TUPLE: 2 fields;
...
A bunch of hex code

But in parent table `accounts`.`user`, in index `PRIMARY`,
the closest match we can find is record:
...
A bunch of hex code
4

10 に答える 10

17

SQLコードの先頭に次のコードを追加することで、「外部キー制約が失敗する」問題を解決しました(これはテーブルに値をインポートするためのものでした)

SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT;
SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS;
SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION;
SET NAMES utf8;
SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0;
SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0;
SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO';
SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0; 

次に、このコードをファイルの最後に追加します

SET SQL_MODE=@OLD_SQL_MODE;
SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS;
SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS;
SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT;
SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS;
SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION;
SET SQL_NOTES=@OLD_SQL_NOTES; 
于 2016-03-18T08:37:06.700 に答える
10

テーブル定義を指定していないので、推測するのは難しいです。しかし、子テーブルの外部キーを変更しようとしているようです。AFAIK、これは違法です。親から変更することはできますが、子テーブルから変更することはできません。

この例を考えてみましょう。

CREATE TABLE parent (
  parent_id INT NOT NULL,
  parent_data int,

  PRIMARY KEY (parent_id)
) ENGINE=INNODB;

CREATE TABLE child1 (
  child1_id INT,
  child1_data INT,
  fk_parent_id INT,

  INDEX par_ind1 (fk_parent_id),

  FOREIGN KEY (fk_parent_id)
    REFERENCES parent(parent_id)
    ON DELETE CASCADE
    ON UPDATE CASCADE
) ENGINE=INNODB;

CREATE TABLE child2 (
  child2_id INT,
  child2_data INT,
  fk_parent_id INT,

  INDEX par_ind2 (fk_parent_id),

  FOREIGN KEY (fk_parent_id)
    REFERENCES parent(parent_id)
    ON DELETE CASCADE
    ON UPDATE CASCADE
) ENGINE=INNODB;

INSERT INTO parent
  (parent_id, parent_data)
  VALUES
  (1, 11),
  (2, 12);

INSERT INTO child1
  (child1_id, child1_data, fk_parent_id)
  VALUES
  (101, 1001, 1),
  (102, 1002, 1),
  (103, 1003, 1),
  (104, 1004, 2),
  (105, 1005, 2);

INSERT INTO child2
  (child2_id, child2_data, fk_parent_id)
  VALUES
  (106, 1006, 1),
  (107, 1007, 1),
  (108, 1008, 1),
  (109, 1009, 2),
  (110, 1010, 2);

次に、これが許可されます。

UPDATE parent
  SET parent_id = 3 WHERE parent_id = 2;

SELECT * FROM parent;
SELECT * FROM child1;
SELECT * FROM child2;

ただし、これはそうではありません。これは、子テーブルから親fkを変更するためです。

UPDATE child1
  SET fk_parent_id = 4 WHERE fk_parent_id = 1;

エラーと非常によく似たエラーが発生します。

Cannot add or update a child row: a foreign key constraint fails (`db_2_b43a7`.`child1`, CONSTRAINT `child1_ibfk_1` FOREIGN KEY (`fk_parent_id`) REFERENCES `parent` (`parent_id`) ON DELETE CASCADE ON UPDATE CASCADE):
于 2012-10-19T04:11:18.937 に答える
5

テーブルに外部制約を作成しているときに、同じ問題に直面していました。この問題を解決する簡単な方法は、最初に親と子のテーブルのバックアップを取り、次に子のテーブルを切り捨てて、もう一度リレーションを作成することです。これで問題が解決することを願っています。

于 2013-09-04T11:17:16.650 に答える
4

これはかなり古いものですが、@Sidupacの答えに役立つのはFOREIGN_KEY_CHECKS=0。です。

データベーススキーマを管理するもの(私の場合はJPA)を使用している場合、この回答はオプションではありませんが、テーブルに「孤立した」エントリ(存在しない可能性のある外部キーを参照)があることが問題である可能性があります。

これは、MySQLテーブルをMyISAMからInnoDBに変換するときによく発生します。これは、参照整合性が前者とは実際には関係がないためです。

于 2019-03-19T13:57:47.500 に答える
1

無関係なタスクで、最近MySQL WorkbenchでMySQLデータベースを起動しました。上記のテーブルのテーブルリレーションを表示すると、以前は何らかの理由で見逃していた「重複」および/または疑似リレーションに気づきました(表示されませんでした)。 PHPMyAdmin FWIWで)。これらの余分な関係を削除すると、問題はすぐに解決されました。

于 2013-08-01T18:44:13.007 に答える
1

更新時のこのようなエラーは、文字セットと照合の違いが原因である可能性があるため、両方のテーブルで同じであることを確認してください。

于 2017-04-12T10:18:52.060 に答える
1

これに対する私の修正は、親テーブルの前に子テーブルにデータを入力する必要があることでした。

私は2つのテーブルを持っていました:電子メールアドレスによってリンクされたUserDetailsとLogin。したがって、ログインテーブルに挿入する前に、まずUserDetailsに挿入する必要がありました。

insert into UserDetails (Email, Name, Telephone, Department) values ('Email', 'Name', 'number', 'IT');

それで:

insert into Login (UserID, UserType, Email, Username, Password) VALUES (001, 'SYS-USR-ADMIN', 'Email', 'Name', 'Password')
于 2021-02-26T14:56:20.970 に答える
0

私はこの問題に直面しました。解決策は、子フィールドのすべてのデータが親フィールドと一致していることを確認することでした。

たとえば、(出席)テーブル内の外部キーを列(employeeName)に追加するとします。

ここで、親は(employees)テーブル、(employeeName)列です。

出席.employeeNameのすべてのデータはemployee.employeeNameと一致する必要があります

于 2019-12-05T04:35:23.977 に答える
0

同じ問題がありましたが、よく見ると、そのキーに主キー値が割り当てられる前に外部キー値をテーブルに入れようとしていたことが原因であることがわかりました。たとえば、「customers」と「films」の2つのテーブルがあり、それぞれ「cust_id」と「film_id」が主キーでした。「customer」は「films」と1対多の関係にあるため、「films」テーブルの外部キーとして「cust_id」を使用しました。しかし、私は最初に「フィルム」テーブルに値を入れようとしていたので、その問題が発生しました。

于 2020-05-08T06:06:29.217 に答える
-1

これが、CSVデータを関連テーブルにインポートするときに同じエラーが発生する場合に役立つことを願っています。私の場合、親テーブルはOKでしたが、外部キーを含む子テーブルにデータをインポートしているときにエラーが発生しました。子テーブルの外部キー制約を一時的に削除した後、データをインポートし、FK列の値が0である値の一部を見つけて驚いた(親テーブルにエラーが発生していないため、明らかにこれがエラーの原因でした)そのPK列のそのような値)。原因は、FK列の前にあるCSV列のデータにコンマが含まれていたためです(これはフィールド区切り文字として使用していました)。CSVファイルの区切り文字を変更すると、問題が解決しました。

于 2015-03-28T09:15:25.173 に答える