Онлайн библиотека PLAM.RU


6.1. Синтаксис CREATE TRIGGER

CREATE [DEFINER = {user | CURRENT_USER}]

TRIGGER trigger_name trigger_time trigger_event

ON tbl_name FOR EACH ROW trigger_stmt


Эта инструкция создает новый триггер. CREATE TRIGGER была добавлена в MySQL 5.0.2. В настоящее время использование требует привилегии SUPER.

Триггер становится связанным с таблицей с именем tbl_name, которое должно обратиться к постоянной таблице. Вы не можете связывать триггер с view или таблицей TEMPORARY.

Когда триггер активизирован, предложение DEFINER определяет привилегии, которые применяются, как описано ниже в этом разделе.

trigger_time задает время действия. Это может быть BEFORE или AFTER, чтобы задать, что триггер активизируется прежде или после инструкции, которая активизировала это.

trigger_event указывает вид инструкции, которая активизирует триггер. Здесь trigger_event может быть одним из следующего:


INSERT: всякий раз, когда новая строка вставлена в таблицу. Например, через команды INSERT, LOAD DATA или REPLACE.


UPDATE: всякий раз, когда строка изменяется. Например, через инструкцию UPDATE.


DELETE: всякий раз, когда строка удалена из таблицы. Например, через инструкции DELETE и REPLACE. Однако, инструкции DROP TABLE и TRUNCATE относительно таблицы НЕ активизируют триггер, потому что они не используют DELETE!

Важно понять, что trigger_event не представляет литеральный тип инструкции SQL, которая активизирует триггер, поскольку это представляет тип операции таблицы. Например, триггер INSERT активизирован не только инструкцией INSERT, но и LOAD DATA, потому что обе инструкции вставляют строки в таблицу.

Не может быть двух триггеров для данной таблицы, которые имеют те же самые время действия и событие. Например, Вы не можете иметь два триггера BEFORE UPDATE для таблицы. Но Вы можете иметь BEFORE UPDATE и BEFORE INSERT или BEFORE UPDATE и AFTER UPDATE.

trigger_stmt задает инструкцию, которая будет выполнена, когда триггер активизируется. Если Вы хотите выполнять много инструкций, используйте операторную конструкцию BEGIN … END. Это также дает возможность Вам использовать те же самые инструкции, которые являются допустимыми внутри сохраненных подпрограмм.

Замечание: в настоящее время триггеры не активизированы каскадными действиями внешнего ключа. Это ограничение будет сниматься как можно скорее.

Обратите внимание: до MySQL 5.0.10 триггер не может содержать прямые ссылки к именам таблиц. С MySQL 5.0.10, Вы можете записывать имена, как показано в этом примере:


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)


Вы можете обратиться к столбцам в подчиненной таблице (таблице, связанной с вызывающей), используя псевдонимы OLD и NEW. OLD.col_name обращается к столбцу существующей строки прежде, чем она модифицируется или удалится. NEW.col_name обращается к столбцу новой строки, которая будет вставлена, или же к существующей строке после того, как она модифицируется.

Предложение DEFINER определяет логин MySQL, который нужно использовать при проверке привилегий доступа в вызове триггера. Это было добавлено в MySQL 5.0.17. Если дано значение user, это должно быть логином MySQL в формате 'user_name'@'host_name' (как в команде GRANT). Требуются переменные user_name и host_name. CURRENT_USER также может быть дан как CURRENT_USER(). Заданное по умолчанию значение DEFINER: пользователь, который выполняет инструкцию CREATE TRIGGER. Это также, как DEFINER = CURRENT_USER.

Если Вы определяете предложение DEFINER, Вы не можете устанавливать значение к любому логину, кроме Вашего собственного, если Вы не имеете привилегию SUPER. Эти правила определяют допустимые значения пользователя в DEFINER:


Если Вы не имеете привилегии SUPER, единственное допустимое значение user: Ваш собственный логин, определенный буквально или используя CURRENT_USER. Вы не можете устанавливать DEFINER к некоторому другому логину.


Если Вы имеете привилегию SUPER, Вы можете определять любое синтаксически допустимое имя пользователя. Если такого логина фактически не существует, будет сгенерировано предупреждение.

Хотя возможно создать триггер с несуществующим значением DEFINER, делать этого не следует, поскольку триггер не будет активизирован, пока DEFINER фактически не существует. Иначе, поведение относительно проверки привилегии неопределенно.

Обратите внимание: так как MySQL в настоящее время требует, чтобы была привилегия SUPER для использования CREATE TRIGGER, только второе из предшествующих правил применяется. MySQL 5.1.6 вводит право TRIGGER и требует, чтобы эта привилегия наличествовала для создания триггера, так что с этой версии оба правила работают, а SUPER требуется только для определения значения DEFINER другого, чем Ваш собственный логин.

Начиная с MySQL 5.0.17, MySQL проверяет привилегии триггера подобно этому:


В момент вызова CREATE TRIGGER пользователь, который выдает инструкцию, должен иметь привилегию SUPER.


При срабатывании триггера привилегии проверены на соответствие DEFINER. Пользователь должен иметь эти привилегии:


SUPER.


SELECT для подчиненной таблицы, если ссылки к столбцам таблицы происходят через OLD.col_name или or NEW.col_name в определении триггера.


UPDATE для подчиненной таблицы, если столбцы таблицы являются адресатами SET NEW.col_name = value, назначенными в определении триггера.


Любые другие привилегии обычно требуются для инструкций, выполненных триггером.

До MySQL 5.0.17, MySQL проверяет привилегии подобно этому:


При вызове CREATE TRIGGER пользователь, который выдает инструкцию, должен иметь привилегию SUPER.


В момент активации триггера привилегии проверены для пользователя, чьи действия заставили триггер сработать. Этот пользователь должен иметь любые привилегии, которые требуются для инструкций, выполняемых триггером.

Обратите внимание, что введение предложения DEFINER меняет значение CURRENT_USER() в определении триггера: функция CURRENT_USER() работает со значением DEFINER в MySQL 5.0.17 (и выше) или с тем пользователем, чьи действия заставили выполниться триггер (до MySQL 5.0.17).









Главная | Контакты | Нашёл ошибку | Прислать материал | Добавить в избранное

Все материалы представлены для ознакомления и принадлежат их авторам.