MySQL Trigger не работает в PHP

TL; DR: запрос работает из MySQL CLI, но НЕ из PHP, как если бы триггеры не были запущены PHP.

У меня есть структура mySQL, которая выглядит так:

  • entity - это "родительская" таблица с id в качестве PK.
  • contact - это «дочерняя» таблица с entity_id в качестве PK и FK на entity.
  • person - это «внучатая» таблица с entity_id в качестве PK и FK на contact.

Я создал несколько триггеров, чтобы, когда я вставляю новую строку в contact, она сначала вставляет новую строку в entity и использует новый id как entity_id. То же для person и contact. Все триггеры сделаны на одной модели, вот одна из них:

DELIMITER #
DROP TRIGGER IF EXISTS contact_insert_trig;
CREATE TRIGGER contact_insert_trig BEFORE INSERT ON `contact`
FOR EACH ROW BEGIN
    INSERT INTO entity (cat_id) values (1);
    SET NEW.entity_id = (SELECT id FROM entity ORDER BY id DESC LIMIT 1);
    SET NEW.entity_cat_id = 1;
END; #

Так, например, когда я вставляю новую строку в person, первый триггер создает строку в contact, которая через второй триггер создает строку в entity, все с соответствующими id.

Это РАБОТАЕТ в MySQL, но НЕ в PHP. Тот же запрос:

INSERT INTO person (first_name, last_name) VALUES ("Bob", "McIntosh")

работает в mySQL CLI (все строки создаются и совпадают), но не работает при вызове с помощью mysqli->query() в PHP7 с ошибкой:

Field 'entity_id' doesn't have a default value

Как я могу заставить его работать и на PHP? Или мне нужно вручную создавать все родительские таблицы?

Хм ... это действительно не должно быть проблемой php. Механизм обнаружения вставки строки не зависит от того, откуда пришел запрос. Это вообще не ответ, но независимо от того, пишете ли вы код, который создает родительские записи в MySQL или php, вы все равно делаете это «вручную», и я склоняюсь к тому, чтобы моя логика была собрана в одном месте. Триггеры легко потерять. Поэтому, хотя я, честно говоря, понятия не имею, почему вы наблюдаете такое поведение, я бы рекомендовал использовать php, а не триггеры из философских соображений.

Jerry 13.05.2018 03:22

Согласитесь на оба счета. Не имеет значения, откуда исходит запрос, значит, я что-то упускаю. Что касается того, что логика находится в одном месте, я заранее решил, что БД должна быть надежной сама по себе. PHP - это только интерфейс, но некоторые люди все еще могут (и должны будут) получить доступ к данным непосредственно из mySQL. Я не хочу, чтобы они могли что-то испортить, создавая / обновляя / удаляя строки. Отсюда и триггеры.

nico7et8 13.05.2018 13:54
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать 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 и хотите разрабатывать...
1
2
348
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Это помогло, теперь запросы работают и с PHP:

SET SESSION sql_mode = 'NO_ENGINE_SUBSTITUTION';

(или не включайте STRICT_TRANS_TABLES).

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