Неможливо додати або оновити дочірню рядок: помилка зовнішнього ключа не вдається


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

Відповіді:


235

Ви отримуєте цю помилку, оскільки ви намагаєтеся додати / оновити рядок table2, який не має дійсного значення для UserIDполя на основі значень, які зберігаються в даний момент table1. Якщо ви опублікуєте ще якийсь код, я можу допомогти вам діагностувати конкретну причину.


PreparedStatement st = connection.prepareStatement ("Вставити в table2 (UserID, PostID, Title, Summary)" + "значення (UserID,?,?,?)");
Том

15
не впевнений, для чого призначений потік; моя відповідь цілком справедлива і правильна.
Брайан Дрісколл

Хм ... напевно, не годиться поєднувати названі параметри з неназваними параметрами у вашому підготовленому операторі. це повинно бути "значення (?,?,?,?)" з відповідним значенням для UserID, вказаним у вашому операторі Execute.
Брайан Дрісколл

Отже, мені потрібно зробити інший оператор SQL, щоб отримати userid з table1?
Том

5
Швидше за все, 0, замініть його на Null, якщо так
Джефрі Ніколсон Карре

123

Це означає , що ви намагаєтеся вставити table2в UserIDзначення , яке не існує в table1.


104

Простим злом може бути відключення перевірки зовнішнього ключа перед виконанням будь-якої операції на столі. Просто запитуйте

SET FOREIGN_KEY_CHECKS=0

Це дозволить вимкнути відповідність зовнішніх ключів до будь-яких інших таблиць. Після закінчення роботи таблиці ввімкніть її ще раз

SET FOREIGN_KEY_CHECKS=1

Це працює для мене багато разів.


Як я ВИКОРИСТОВУЮ ??
Сахін з Пуна

2
@SachinfromPune просто додайте SET FOREIGN_KEY_CHECKS = 0; при запуску файлу mysql і SET FOREIGN_KEY_CHECKS = 1; наприкінці файлу mysql,
переімпортуйте

1
Хіба це не проблематично? Ви втрачаєте референтну цілісність, правда?
roadrunner66

Цілісність посилань підтримується наявністю правильних записів індексу. Поки ви маєте свої ключі та індекси правильно, ви повинні мати можливість відключити перевірку клавіш під час групового введення.
Вернон Кінан

46

Я виявив ще один дивний випадок: Якщо ви випадково створили сторонній ключ із таблиці InnoDB до таблиці MyISAM, MySQL видає цю помилку під час вставки, навіть якщо дані в іншому випадку дійсні.

Дивіться http://nick.zoic.org/art/mysql-foreign-key-error/


1
Так, у мене така ж проблема. Дві таблиці повинні бути InnoDB!
смарагдовий

2
У мене була така ж проблема, дякую за пораду. Ось посилання на MySQL документацію про те, як перетворити таблиці з MyISAM в InnoDB dev.mysql.com/doc/refman/5.7/en/… TLDR: ALTER TABLE table_name ENGINE = InnoDB;
Гільгерме Ваз

Дійсно, так було у моїй базі даних. Я вирішив змінити движок MyISAM на InnoDB. Нарешті, я можу працювати з базою даних так, як хотів.
Майк

17

Ви отримуєте цю помилку, оскільки є якесь значення int, table2.UserIDяке не існує table1.UserID(я думаю, що ви встановили table2.UserIDзначення вручну перед тим, як створити цей зовнішній ключ).
Один приклад для цієї сцени: table1.UserIDотримати значення 1,2,3 та table2.UserIDотримати значення 4 (додати вручну). Тому , коли ви робите зовнішній ключ, вони не можуть знайти UserID = 4з table1і помилка буде ocurse.
Щоб виправити цю помилку, просто видаліть UserID = 4з них table2або ви можете їх спорожнити, а потім створити зовнішній ключ і.
Удачі!


11

Це знадобило мені час, щоб розібратися. Простіше кажучи, таблиця, на яку посилається інша таблиця, вже містить дані, і одне або кілька її значень не існує в батьківській таблиці.

наприклад, таблиця2 має такі дані:

UserID    PostID    Title    Summary
5         1         Lorem    Ipsum dolor sit

Таблиця1

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

Якщо ви спробуєте ALTER table2 та додати іноземний ключ, то запит не вдасться, оскільки UserID = 5 не існує в Table1.


10

Якщо ви вставили рядок у таблицю 1 перед тим, як створити зовнішній ключ у таблиці 2, ви отримаєте помилку обмеження іноземного ключа, оскільки значення автоматичного збільшення 2 у таблиці 1 та 1 у таблиці 2. Щоб вирішити це, вам потрібно обрізати таблицю 1 і встановити значення автоматичного збільшення на 1. Потім можна додати таблицю 2.


10

Переконайтеся, що ви встановили движок бази даних на InnoDB, оскільки в MyISAM зовнішній ключ та транзакція не підтримуються


2
ALTER TABLE my_table ENGINE = InnoDB;
Bishwas Mishra

7

Ще трохи виправте: зробіть JoinColumn 'nullable = true' у Table1 та поле UserID 'inserttable = false' та 'nullable = true' у Table2.

У таблиці1 Суб'єкт:

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

У таблиці2 Суб'єкт:

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

Ця відповідь повністю вирішила мою проблему, дуже дякую, що поділилися цим. Ключовим для мене було додавання @Column (inserttable = false, nullable = true) до файлу, який я використовую як ключ foraeing у своєму дочірньому об'єкті / таблиці.
Ізраїль

6

У мене просто була та сама проблема, рішення легко.

Ви намагаєтеся додати ідентифікатор у дочірню таблицю, яка не існує в батьківській таблиці.

перевірте добре, оскільки InnoDB має помилку, яка іноді збільшує стовпчик auto_increment без додавання значень, наприклад, INSERT ... ON DUPLICATE KEY


серйозно? не вставляйте ідентифікатор, який не існує ... просто перевірте
Blaztix

5

У мене було подібне питання. Ви намагаєтеся застосувати іноземний ключ до таблиці, яка містить вміст, і стовпець не зводиться до нуля. У вас є два варіанти.

  1. Зробіть стовпець, до якого потрібно застосувати обмеження іноземних ключів, щоб бути нульовим. Таким чином, зовнішній ключ застосовуватиметься, знаючи, що деякі поля можуть бути нульовими. ( Це я і зробив. )
  2. Створіть стовпець, на який потрібно застосувати обмеження іноземного ключа, напишіть запит, щоб вставити іноземний ключ у стовпець, а потім застосуйте обмеження іноземного ключа. ( Не пробував цього, але це має працювати )

4

Переконайтеся, що значення, яке ви вставляєте в іноземний ключ, існує у батьківській таблиці. Це мені допомогло. Наприклад, якщо ви вставили user_id = 2в table.2, але table.1не має user_id = 2, обмеження призведе до помилки. Моє було помилковим кодом №1452, щоб бути точним. Сподіваюся, це допоможе будь-кому іншому з тією ж проблемою!


3

У мене був той самий випуск, і причиною було те, що я мав рядок у першій таблиці перед тим, як додати зовнішній ключ.


1

Я також зіткнувся з тією ж проблемою, і проблема полягала в тому, що значення записів моєї батьківської таблиці не збігається зі значенням таблиці зовнішнього ключа. Тому, будь ласка, спробуйте після очищення всіх рядків.


Обмеження вимагає, щоб користувачі, на які посилається таблиця2, вже були визначені в таблиці1.
сорак

1

У випадку, якщо рішення, надані іншими, не спрацювали. Тоді вам слід спробувати перевірити Бази даних двигунів батьківських та дочірніх таблиць. У моєму випадку у мене було встановлено двигун батьківських таблиць на "MyISAM", змінивши його на InnoDB зафіксовано.

Сподіваюся, це допомагає іншим, хто застряг, як я.



0

Ще один дивний випадок, який дав мені цю помилку. Я помилково посилав свої зовнішні ключі на первинний ключ id. Це було викликано неправильними командами alter table. Я дізнався це, запитуючи таблицю INFORMATION_SCHEMA (Дивіться цю відповідь stackoverflow)

Таблиця була настільки заплутана, що її неможливо було виправити жодними командами ALTER TABLE . Нарешті я скинув стіл і реконструював його. Це позбулося цілісностіError.


0

Можливо, поки ви додали userIDстовпець, для цієї певної таблиці є дані, що вона створена, щоб вона мала значення за замовчуванням 0, спробуйте додати стовпець безNOT NULL


0

Я також отримав цю помилку: "Неможливо додати або оновити дочірню рядок: помилка зовнішнього ключа не вдається". Я отримав помилку під час додавання нового рядка до батьківської таблиці

Проблема полягала в тому, що обмеження зовнішнього ключа було визначено на батьківській таблиці замість дочірньої таблиці.


0

Якщо ви використовуєте індекс mysql або відношення між таблицями, спочатку ви видаляєте стовпчики (наприклад: city_id) і створюєте нові стовпці з таким же ім'ям (наприклад: city_id). Потім спробуйте знову ...


0

Чи є наявні дані, які містить таблиця? Якщо так, спробуйте очистити всі дані в таблиці, до якої потрібно додати іноземний ключ. Потім знову запустіть код (додайте закордонний ключ).

Я стикався з цією проблемою стільки разів. Це очищення всіх даних таблиці працює, коли ви хочете додати зовнішній ключ до існуючої таблиці.

Сподіваюся, це працює :)


0

Видаліть індекси з поля UserID таблиці2. Для мене це підходить


0

Ця помилка виникає, коли потрібно додати іноземний ключ зі значеннями, які не існують у первинному ключі батьківської таблиці. Ви повинні бути впевнені, що новий зовнішній ключ UserID в table2 має значення, які існують у первинному ключі table1, іноді за замовчуванням він є нульовим або рівним 0.

Ви можете спочатку оновити всі поля зовнішнього ключа в table2 зі значенням, яке існує в первинному ключі таблиці1.

update table2 set UserID = 1 where UserID is null

Якщо ви хочете додати різні UserID, ви повинні змінити кожен рядок зі значеннями, які ви хочете.


-1

обмеження зовнішнього ключа дитячого столу не вдається

Ця проблема може виникнути через наступну причину:

Якщо ви робите це у весняному mvc, вам потрібно чітко описати тип id, оскільки іноді mysql не вдається розпізнати тип id. тому ви явно встановлюєте, як в обох таблицях у вашому класі сутності@GeneratedValue (strategy = GenerationType.IDENTITY)

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.