При вставке данных в таблицу все работает как надо. Однако, глядя на таблицы, я заметил, что ни один из внешних ключей не работает. Вот таблица 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
, CONSTRAINTFK_BaseID
FOREIGN KEY (BaseID
) REFERENCESpizzabase
(BaseID
))
Что вы получите в результате SHOW VARIABLES LIKE '% FORE%' и SHOW global VARIABLES LIKE '% FORE%'
Вы спрашиваете, почему CONSTRAINT
не препятствует тому, чтобы столбец был NULL
, или вы спрашиваете, почему ваш запрос INSERT
не заполняет столбец?
А где определение PizzaBase
@ Script47 Код вставки PHP: phpfiddle.org/main/code/j9nx-hzbh
@deceze Я относительно новичок в MySQL и PHP, поэтому я пытаюсь понять, почему значение null в таблице Pizza, я предполагаю, что что-то не так с запросом вставки, указанным выше.
Глядя на ваш связанный код (вставьте код в сам вопрос!): Вы никогда ничего не помещаете в столбец ToppingID
.
@deceze Насколько я понимаю, ToppingID INT AUTO_INCREMENT
будет автоматически увеличивать значение на 1 для каждой добавленной начинки? Кроме того, на моем снимке экрана самой таблицы PizzaTopping указано значение «1», так почему в таблице «Пицца» оно равно нулю?
@BenFoster: да, это поле ИИ в таблице, в которой он ОПРЕДЕЛЕН, а не таблица, на которую указывает ссылка. В справочной таблице также необходимо указать идентификатор начинки. Рассмотрите возможность чтения на отношения между таблицами.
Вставка чего-либо в PizzaToppings
не приводит к автоматическому помещению чего-либо в Pizza
! База данных не сможет узнать, в какую строку Pizza
поместить ToppingID
.
Итак, моя ошибка заключалась в предположении, что внешний ключ передаст ToppingID
, тогда как на самом деле для этого потребовалось бы что-то вроде соединения?
Каждый запрос стоит сам по себе, база данных не может сделать вывод о том, что вы устанавливаете какое-то логическое соединение между двумя независимыми запросами, и хотела бы перекрестно вставить некоторые идентификаторы. Да, это предположение было проблемой. Вам нужно сначала вставить в PizzaToppings
, а затем вставить в Pizza
с новым идентификатором, который вы только что получили от PizzaToppings
.
@deceze Хорошо, я попробовал то, что вы предложили, и попытался вставить значения внешнего ключа в таблицу Pizza, используя этот код: phpfiddle.org/main/code/urdi-j2cb. Однако это вызывает ошибку: Нарушение ограничения целостности: 1452 Невозможно добавить или обновить дочернюю строку: ограничение внешнего ключа не выполнено (pizzadelivery
.pizza
, ОГРАНИЧЕНИЕ FK_BaseID
FOREIGN KEY (BaseID
) ССЫЛКИ pizzabase
(BaseID
))
Обновите свой вопрос, не ожидайте, что он будет решен в ветке комментариев.
$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();
Где ваш вставной код?