Spec-Zone .ru
спецификации, руководства, описания, API
|
Чтобы создать триггер или отбросить триггер, используйте CREATE TRIGGER
или DROP
TRIGGER
оператор, описанный в Разделе 13.1.15,"CREATE TRIGGER
Синтаксис", и Раздел
13.1.24,"DROP TRIGGER
Синтаксис".
Вот простой пример, который связывает триггер с таблицей для INSERT
операторы. Триггер действует как аккумулятор, суммируя значения,
вставленные в один из столбцов таблицы.
mysql>CREATE TABLE account (acct_num INT, amount DECIMAL(10,2));
Query OK, 0 rows affected (0.03 sec)mysql>CREATE TRIGGER ins_sum BEFORE INSERT ON account
->FOR EACH ROW SET @sum = @sum + NEW.amount;
Query OK, 0 rows affected (0.06 sec)
CREATE TRIGGER
оператор создает названный триггер ins_sum
это связывается с account
таблица. Это также
включает пункты, которые определяют триггерное время активации, инициирующее событие, и что сделать, когда
триггер активируется:
Ключевое слово BEFORE
указывает триггерное время
действия. В этом случае триггер должен активироваться перед каждой строкой, вставленной в таблицу.
Другое допустимое ключевое слово здесь AFTER
.
Ключевое слово INSERT
указывает на тип работы, которая
активирует триггер. В примере, INSERT
операторы вызывают триггерную активацию. Можно также создать триггеры для DELETE
и UPDATE
операторы.
Оператор после FOR EACH ROW
определяет оператор, чтобы
выполниться каждый раз, когда триггер активируется, который происходит однажды для каждой строки, на
которую влияет оператор инициирования. В примере инициированный оператор является простым SET
это накапливает в пользовательскую переменную значения,
вставленные в amount
столбец. Оператор обращается к столбцу как NEW.amount
что означает "значение amount
столбец, который будет вставлен в новую строку."
Чтобы использовать триггер, обнулите переменную аккумулятора, выполнитесь INSERT
оператор, и затем видит то, что оценивает переменную, имеет позже:
mysql>SET @sum = 0;
mysql>INSERT INTO account VALUES(137,14.98),(141,1937.50),(97,-100.00);
mysql>SELECT @sum AS 'Total amount inserted';
+-----------------------+| Total amount inserted |+-----------------------+| 1852.48 |+-----------------------+
В этом случае, значение @sum
после INSERT
оператор выполнился, 14.98 + 1937.50 - 100
,
или 1852.48
.
Чтобы уничтожить триггер, используйте a DROP
TRIGGER
оператор. Следует определить имя схемы, если триггер не находится в схеме значения по
умолчанию:
mysql> DROP TRIGGER
test.ins_sum;
Триггеры для таблицы также отбрасываются, если Вы отбрасываете таблицу.
Триггерные имена существуют в пространстве имен схемы, означая, что у всех триггеров должны быть уникальные имена в пределах схемы. У триггеров в различных схемах может быть то же самое имя.
В дополнение к требованию, чтобы триггерные имена быть уникальными для схемы, были другие ограничения на типы
триггеров, которые можно создать. В частности у Вас не может быть двух триггеров для таблицы, у которых есть то
же самое время активации и событие активации. Например, невозможно определить два BEFORE
INSERT
триггеры или два AFTER UPDATE
триггеры для таблицы. Это должно
редко быть существенным ограничением, потому что возможно определить триггер, который выполняет многократные
операторы при использовании BEGIN
... END
конструкция составного оператора после FOR EACH ROW
. (Пример
появляется позже в этом разделе.)
OLD
и NEW
ключевые слова включают Вам к столбцам
доступа в строках, на которые влияет триггер. (OLD
и NEW
не являются чувствительными к регистру.) В INSERT
триггер, только NEW.
может использоваться; нет никакой старой строки. В a col_name
DELETE
триггер, только OLD.
может использоваться; нет
никакой новой строки. В col_name
UPDATE
триггер, можно использовать OLD.
обратиться к столбцам строки прежде, чем это будет
обновлено и col_name
NEW.
обратиться к
столбцам строки после того, как это обновляется. col_name
Столбец, названный с OLD
только для чтения. Можно обратиться к этому (если Вы
имеете SELECT
полномочие), но не изменяют это. Столбец, названный с NEW
может быть упомянут, если Вы имеете SELECT
полномочие для этого. В a BEFORE
триггер,
можно также изменить его значение с SET NEW.
если Вы имеете col_name
= value
UPDATE
полномочие для этого. Это означает, что можно использовать триггер,
чтобы изменить значения, которые будут вставлены в новую строку или которые используются, чтобы обновить строку.
(Такой SET
оператор не имеет никакого эффекта в AFTER
инициируйте, потому что изменение строки уже произошло.)
В a BEFORE
триггер, NEW
значение для AUTO_INCREMENT
столбец 0, не автоматически сгенерированный порядковый номер, который
будет сгенерирован, когда новая запись фактически будет вставлена.
OLD
и NEW
расширения MySQL триггеров.
При использовании BEGIN ...
END
создайте, можно определить триггер, который выполняет многократные операторы. В пределах BEGIN
блок, также можно использовать другой синтаксис, который разрешается в пределах
сохраненных подпрограмм, таких как условные выражения и циклы. Однако, так же, как для сохраненных подпрограмм,
если Вы используете mysql программу, чтобы определить триггер, который выполняет
многократные операторы, необходимо пересмотреть mysql разделитель оператора так, чтобы можно было
использовать ;
разделитель оператора в пределах триггерного определения. Следующий
пример иллюстрирует эти тезисы. Это определяет UPDATE
триггер, который проверяет
новое значение, которое будет использоваться для того, чтобы обновить каждую строку, и изменяет значение, чтобы
быть в пределах диапазона от 0 до 100. Это должно быть a BEFORE
инициируйте, потому
что значение должно быть проверено прежде, чем оно будет использоваться, чтобы обновить строку:
mysql>delimiter //
mysql>CREATE TRIGGER upd_check BEFORE UPDATE ON account
->FOR EACH ROW
->BEGIN
->IF NEW.amount < 0 THEN
->SET NEW.amount = 0;
->ELSEIF NEW.amount > 100 THEN
->SET NEW.amount = 100;
->END IF;
->END;//
mysql>delimiter ;
Может быть легче определить хранимую процедуру отдельно и затем вызвать это от триггера, используя простое CALL
оператор. Это также выгодно, если Вы хотите выполнить тот же самый код изнутри нескольких триггеров.
Есть некоторые ограничения на то, что может появиться в операторах, которые триггер выполняет когда активировано:
Триггер не может использовать CALL
оператор, чтобы вызвать хранимые процедуры, которые возвращают данные клиенту или тому использованию
динамический SQL. (Хранимым процедурам разрешают возвратить данные триггеру через OUT
или INOUT
параметры.)
Триггер не может использовать операторы, которые явно или неявно начинают или
заканчивают транзакцию такой как START TRANSACTION
, COMMIT
, или ROLLBACK
.
MySQL обрабатывает ошибки во время триггерного выполнения следующим образом:
Если a BEFORE
инициируйте сбои, работа на
соответствующей строке не выполняется.
A BEFORE
триггер активируется попыткой вставить или изменить строку, независимо от того, успешно
выполняется ли попытка впоследствии.
AFTER
триггер выполняется только если BEFORE
триггер (если кто-либо) и работа строки оба выполняется успешно.
Ошибка во время любого a BEFORE
или AFTER
инициируйте результаты в отказе всего оператора, который вызвал
триггерный вызов.
Для транзакционных таблиц отказ оператора должен вызвать откат всех изменений, выполняемых оператором. Отказ триггера заставляет оператор перестать работать, таким образом, триггерный отказ также вызывает откат. Для нетранзакционных таблиц такой откат не может быть сделан, так, хотя оператор перестал работать, любые изменения, выполняемые до точки ошибки, остаются в силе.
Триггеры могут содержать прямые ссылки на таблицы по имени, такие как названный триггер testref
показанный в этом примере:
CREATE TABLE test1(a1 INT);CREATE TABLE test2(a2 INT);CREATE TABLE test3(a3 INT NOT NULL AUTO_INCREMENT PRIMARY KEY);CREATE TABLE test4( a4 INT NOT NULL AUTO_INCREMENT PRIMARY KEY, b4 INT DEFAULT 0);delimiter |CREATE TRIGGER testref BEFORE INSERT ON test1 FOR EACH ROW BEGIN INSERT INTO test2 SET a2 = NEW.a1; DELETE FROM test3 WHERE a3 = NEW.a1; UPDATE test4 SET b4 = b4 + 1 WHERE a4 = NEW.a1; END;|delimiter ;INSERT INTO test3 (a3) VALUES (NULL), (NULL), (NULL), (NULL), (NULL), (NULL), (NULL), (NULL), (NULL), (NULL);INSERT INTO test4 (a4) VALUES (0), (0), (0), (0), (0), (0), (0), (0), (0), (0);
Предположите, что Вы вставляете следующие значения в таблицу test1
как показано
здесь:
mysql>INSERT INTO test1 VALUES
->(1), (3), (1), (7), (1), (8), (4), (4);
Query OK, 8 rows affected (0.01 sec)Records: 8 Duplicates: 0 Warnings: 0
В результате эти четыре таблицы содержат следующие данные:
mysql>SELECT * FROM test1;
+------+| a1 |+------+| 1 || 3 || 1 || 7 || 1 || 8 || 4 || 4 |+------+8 rows in set (0.00 sec)mysql>SELECT * FROM test2;
+------+| a2 |+------+| 1 || 3 || 1 || 7 || 1 || 8 || 4 || 4 |+------+8 rows in set (0.00 sec)mysql>SELECT * FROM test3;
+----+| a3 |+----+| 2 || 5 || 6 || 9 || 10 |+----+5 rows in set (0.00 sec)mysql>SELECT * FROM test4;
+----+------+| a4 | b4 |+----+------+| 1 | 3 || 2 | 0 || 3 | 1 || 4 | 2 || 5 | 0 || 6 | 0 || 7 | 1 || 8 | 1 || 9 | 0 || 10 | 0 |+----+------+10 rows in set (0.00 sec)