Для примера возьмем такую минималистичную табличку:
Код:
CREATE TABLE `articles` (
`id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
`name` VARCHAR(255) NOT NULL,
`title` VARCHAR(255) NOT NULL,
PRIMARY KEY (`id`)
) engine=innodb;
Выполним запрос на вставку двух записей:
Код:
INSERT INTO `articles` VALUES
(DEFAULT, 'sample', 'sample'),
(DEFAULT, 'sample 1', 'sample 2')
;
Я выполняю команды из консоли mysql, мне показывается результат. Все вставилось успешно:
Код:
Query OK, 2 rows affected (0.01 sec)
Records: 2 Duplicates: 0 Warnings: 0
Теперь создадим триггер на вставку данных. Он срабатывает при каждой вставке.
Код:
DELIMITER $$
CREATE TRIGGER `before_insert_articles`
BEFORE INSERT ON `articles`
FOR EACH ROW
BEGIN
IF NEW.name = NEW.title
THEN
SIGNAL SQLSTATE '02000' SET MESSAGE_TEXT = 'Error: name = title!';
END IF;
END$$
DELIMITER ;
Перед строкой "DELIMITER ;" MySQL должен вывести успех:
Код:
Query OK, 0 rows affected (0.00 sec)
Если этого не произошло, то возможные причины:
- такой триггер уже есть (не наш случай)
- ошибка синтаксиса (я проверил, не наш случай)
- текущему пользователю запрещено создавать триггеры. такое может быть на шаред-хостингах. смотрите выхлоп "show grants;"
Продолжим. Попробуем вставить одну "неправильную" запись:
Код:
INSERT INTO `articles` VALUES
(DEFAULT, 'sample', 'sample');
Должно вывестись:
Код:
> ERROR 1643 (02000): Error: name = title!
Вставка не произошла. Попробуем случай посложнее, где вторая строка проходит условие:
Код:
INSERT INTO `articles` VALUES
(DEFAULT, 'sample', 'sample'),
(DEFAULT, 'sample 3', 'sample 4')
;
Получим ту же самую ошибку:
Код:
> ERROR 1643 (02000): Error: name = title!
Это произошло потому что триггер работает на уровне запросов.
У нас в таблице уже есть две записи:
Код:
mysql> select * from articles;
+----+----------+----------+
| id | name | title |
+----+----------+----------+
| 1 | sample | sample |
| 2 | sample 1 | sample 2 |
+----+----------+----------+
2 rows in set (0.00 sec)
Теперь попробуем сделать "правильную" вторую запись "неправильной":
Код:
mysql> UPDATE `articles` SET name = title;
Query OK, 1 row affected (0.01 sec)
Rows matched: 2 Changed: 1 Warnings: 0
mysql> select * from articles;
+----+----------+----------+
| id | name | title |
+----+----------+----------+
| 1 | sample | sample |
| 2 | sample 2 | sample 2 |
+----+----------+----------+
2 rows in set (0.00 sec)
Запрос выполнился успешно. Если необходимо задать ограничение на обновление, следует создать еще один аналогичный триггер:
Код:
BEFORE UPDATE ON `articles`