Все внешние ключи равны нулю

При вставке данных в таблицу все работает как надо. Однако, глядя на таблицы, я заметил, что ни один из внешних ключей не работает. Вот таблица Pizza, которая должна брать внешние ключи BaseID и ToppingID из других таблиц:

Все внешние ключи равны нулю

Как показано на рисунке выше, ToppingID имеет значение NULL. В то время как в реальной таблице PizzaToppings, как показано ниже, ToppingID имеет значение нет null:

Все внешние ключи равны нулю

В настоящее время это происходит со всеми моими внешними ключами в базе данных.

Однако это вызывает ошибку:

Integrity constraint violation: 1452 Cannot add or update a child row: a foreign key constraint fails (pizzadelivery.pizza, CONSTRAINT FK_BaseID FOREIGN KEY (BaseID) REFERENCES pizzabase (BaseID))

Где ваш вставной код?

Script47 01.05.2018 11:57

Что вы получите в результате SHOW VARIABLES LIKE '% FORE%' и SHOW global VARIABLES LIKE '% FORE%'

P.Salmon 01.05.2018 11:59

Вы спрашиваете, почему CONSTRAINT не препятствует тому, чтобы столбец был NULL, или вы спрашиваете, почему ваш запрос INSERT не заполняет столбец?

deceze 01.05.2018 11:59

А где определение PizzaBase

RiggsFolly 01.05.2018 12:00

@ Script47 Код вставки PHP: phpfiddle.org/main/code/j9nx-hzbh

Ben Foster 01.05.2018 12:03
Примечание: @BenFoster ваш код на самом деле довольно хорошо написан по сравнению с другими вопросами. Подумайте о том, чтобы поработать и над форматированием вашего вопроса в будущем.
Script47 01.05.2018 12:05

@deceze Я относительно новичок в MySQL и PHP, поэтому я пытаюсь понять, почему значение null в таблице Pizza, я предполагаю, что что-то не так с запросом вставки, указанным выше.

Ben Foster 01.05.2018 12:05

Глядя на ваш связанный код (вставьте код в сам вопрос!): Вы никогда ничего не помещаете в столбец ToppingID.

deceze 01.05.2018 12:07

@deceze Насколько я понимаю, ToppingID INT AUTO_INCREMENT будет автоматически увеличивать значение на 1 для каждой добавленной начинки? Кроме того, на моем снимке экрана самой таблицы PizzaTopping указано значение «1», так почему в таблице «Пицца» оно равно нулю?

Ben Foster 01.05.2018 12:10

@BenFoster: да, это поле ИИ в таблице, в которой он ОПРЕДЕЛЕН, а не таблица, на которую указывает ссылка. В справочной таблице также необходимо указать идентификатор начинки. Рассмотрите возможность чтения на отношения между таблицами.

Script47 01.05.2018 12:11

Вставка чего-либо в PizzaToppings не приводит к автоматическому помещению чего-либо в Pizza! База данных не сможет узнать, в какую строку Pizza поместить ToppingID.

deceze 01.05.2018 12:12

Итак, моя ошибка заключалась в предположении, что внешний ключ передаст ToppingID, тогда как на самом деле для этого потребовалось бы что-то вроде соединения?

Ben Foster 01.05.2018 12:13

Каждый запрос стоит сам по себе, база данных не может сделать вывод о том, что вы устанавливаете какое-то логическое соединение между двумя независимыми запросами, и хотела бы перекрестно вставить некоторые идентификаторы. Да, это предположение было проблемой. Вам нужно сначала вставить в PizzaToppings, а затем вставить в Pizza с новым идентификатором, который вы только что получили от PizzaToppings.

deceze 01.05.2018 12:18

@deceze Хорошо, я попробовал то, что вы предложили, и попытался вставить значения внешнего ключа в таблицу Pizza, используя этот код: phpfiddle.org/main/code/urdi-j2cb. Однако это вызывает ошибку: Нарушение ограничения целостности: 1452 Невозможно добавить или обновить дочернюю строку: ограничение внешнего ключа не выполнено (pizzadelivery.pizza, ОГРАНИЧЕНИЕ FK_BaseID FOREIGN KEY (BaseID) ССЫЛКИ pizzabase (BaseID))

Ben Foster 01.05.2018 12:40

Обновите свой вопрос, не ожидайте, что он будет решен в ветке комментариев.

deceze 01.05.2018 12:41
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
2
15
81
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий
$toppingID = $stmt -> fetch(PDO::FETCH_ASSOC);

$toppingID - это массив, который, вероятно, будет связан как строка 'Array' в вашем последнем запросе, который, очевидно, является несуществующим идентификатором и нарушает ваше ограничение (это то, что делают ограничения, они гарантируют, что данные присутствуют в другой таблице).

Вы также не хотите использовать MAX() для получения идентификатора; не гарантируется, что новый идентификатор имеет наибольшее число в столбце, и это небезопасно от условий гонки, если вы выполняете несколько запросов параллельно. Вы хотите получить последний идентификатор вставки:

$stmt = $pdo->prepare('INSERT INTO PizzaToppings ...');
...
$stmt->execute();
$toppingId = $pdo->lastInsertId();

$stmt = $pdo->prepare('INSERT INTO PizzaBase ...');
...
$stmt->execute();
$baseId = $pdo->lastInsertId();

$stmt = $pdo->prepare('INSERT INTO Pizza (..., ToppingID, BaseID) VALUES (..., :ToppingID, :BaseID)');
...
$stmt->bindParam(':ToppingID',$toppingId);
$stmt->bindParam(':BaseID',$baseId);
$stmt->execute();

Другие вопросы по теме