#mysql #enums #triggers #mariadb
Вопрос:
Предполагая, что у меня есть следующая таблица:
CREATE TABLE `test` (
`Id` INT(11) NOT NULL AUTO_INCREMENT,
`Value` ENUM('VAL1','VAL2') NOT NULL,
PRIMARY KEY (`Id`) USING BTREE
) ENGINE=InnoDB;
и следующий триггер:
DELIMITER $
CREATE TRIGGER `test_before_insert` BEFORE INSERT ON `test` FOR EACH ROW BEGIN
SET NEW.`Value` := 'VAL1';
END $
DELIMITER ;
Теперь я могу вставить несколько строк, но если я использую недопустимый тип перечисления, я получаю ошибку:
INSERT INTO test VALUES (NULL, 'VAL2'); // Statement ok, "Value" is set to 'VAL1'
INSERT INTO test VALUES (NULL, 'VAL5'); // Exception 'SQL Fehler (1265): Data truncated for column 'Value' at row 1'
Похоже, перед срабатыванием триггера-срабатывает проверка допустимых значений перечисления INSERT
. Это почему? Как я могу установить триггер для изменения недопустимых перечислений на допустимые?
Я видел много примеров, когда такого поведения, по-видимому, не происходит. Может ли это быть неправильной конфигурацией? Мы используем MariaDB 10.5.9.
Комментарии:
1. Да, проверка типа данных выполняется каждый раз: перед триггером, в триггере, между триггерами, после ПЕРЕД триггерами и перед вставкой. ВСТАВКА не зависит от триггеров, триггеры не зависят друг от друга. Список параметров должен быть правильным в каждой точке. И это нельзя изменить. Видишь dbfiddle.uk/…
2. Но что с такими примерами, как joshuaotwell.com/… ? Кстати, dbfiddle.uk … спасибо вам за ссылку! 😉
3. В примере значение ПЕРЕЧИСЛЕНИЯ сравнивается с нулем
0
— это не значение списка ПЕРЕЧИСЛЕНИЙ, а значение индекса перечисления, и нулевое значение означает, что «была установлена пустая строка». Это законно.4. @Akina, Пожалуйста, публикуйте свои ответы как ответы, а не как комментарии. Если вы удовлетворите вопрос пользователя, он будет двигаться дальше, и в Stack Overflow будет все больше «неотвеченных» вопросов.
5. Извините, но я не понимаю. Я думаю, что ПЕРЕЧИСЛЕНИЕ = 0 означает недопустимое значение, как описано в тексте, а не пустую строку типа «, которая должна быть определена в определении ПЕРЕЧИСЛЕНИЯ как другое значение. И какой смысл имеет строка
SET NEW.kind = 'other';
в примере триггера, если это значение нельзя вставить в таблицу? Подводя итог, невозможно изменить перечисления в триггерах, если допустимые значения не содержат как СТАРЫХ, так и НОВЫХ значений?
Ответ №1:
Акина (см. Первый комментарий) права, невозможно изменить неизвестное ENUM
значение даже в триггере.
Решение в моем случае состояло в том, чтобы включить все возможные значения в ENUM
список -. Таким образом, триггер может выполнить свою работу и изменить «запрещенные» значения на разрешенные. Единственное предостережение заключается в том, что теперь некоторые ENUM
значения не используются в данных.