Spec-Zone .ru
спецификации, руководства, описания, API

18.3.1. Триггерный Синтаксис и Примеры

Чтобы создать триггер или отбросить триггер, используйте 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 таблица. Это также включает пункты, которые определяют триггерное время активации, инициирующее событие, и что сделать, когда триггер активируется:

Чтобы использовать триггер, обнулите переменную аккумулятора, выполнитесь 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.col_name может использоваться; нет никакой старой строки. В a 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 оператор. Это также выгодно, если Вы хотите выполнить тот же самый код изнутри нескольких триггеров.

Есть некоторые ограничения на то, что может появиться в операторах, которые триггер выполняет когда активировано:

MySQL обрабатывает ошибки во время триггерного выполнения следующим образом:

Триггеры могут содержать прямые ссылки на таблицы по имени, такие как названный триггер 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)