При выполнении команд добавления, изменения и удаления записей сервер создает две специальные таблицы: inserted и deleted.
В них содержатся списки строк, которые будут вставлены или будут удалены по завершении транзакции.
Структура таблиц inserted и deleted идентична структуре таблиц, для которой определяется триггер. Для каждого триггера создается свой комплект таблиц inserted и deleted, поэтому никакой другой триггер не сможет получить к ним доступ.
В зависимости от типа операции, вызвавшей выполнение триггера, содержимое таблицinserted и deleted может быть разным:
• если дается команда INSERT - в таблицеinserted содержатся все строки, которые пользователь пытается вставить в таблицу; при этом в таблице deleted не будет ни одной строки; после завершения триггера все строки из таблицы inserted переместятся в исходную таблицу;
• если дается команда DELETE - в таблице deleted будут содержаться все строки, которые пользователь попытается удалить; триггер может проверить каждую строку и определить, разрешено ли ее удаление; при этом в таблице inserted не окажется ни одной строки;
• если дается команда UPDATE- при ее выполнении в таблице deleted находятся старые значения строк, которые будут удалены при успешном завершении триггера. Новые значения строк содержатся в таблице inserted. Эти строки добавятся в исходную таблицу после успешного выполнения триггера.
Для получения информации о количестве строк, которое будет изменено при успешном завершении триггера, можно использовать функцию @@ROWCOUNT; она возвращаетколичество строк, обработанных последней командой. Следует подчеркнуть, что триггер запускается не при попытке
изменить конкретную строку, а в момент выполнения команды изменения. Одна такая команда воздействует на множество строк, поэтому триггер должен обрабатывать все эти строки.
Если триггер обнаружил, что из 100 вставляемых, изменяемых или удаляемых строк хотя бы одна строка не удовлетворяет тем или иным условиям, то никакая строка не будет вставлена, изменена или удалена. Такое поведение обусловлено требованиями транзакции - должны быть выполнены либо все модификации, либо ни одной.
Триггер выполняется как неявно определенная транзакция, поэтому внутри триггера допускается применение команд управления транзакциями. При обнаружении нарушения ограничений целостности для прерывания выполнения триггера и отмены всех изменений, которые пытался выполнить пользователь, необходимо использовать команду ROLLBACK TRANSACTION.
Для получения списка столбцов, вызвавших выполнение триггера и измененных при выполнении команд INSERT или UPDATE, можно использовать функцию COLUMNS_UPDATED(). Она возвращает двоичное число, каждый бит которого, начиная с младшего, соответствует одному столбцу таблицы (в порядке следования столбцов при создании таблицы). Если бит установлен в значение «1», то соответствующий столбец был изменен.
Кроме того, факт изменения столбца определяет и функция
UPDATE (имя_столбца).
Для удаления триггера используется команда
DROP TRIGGER {имя_триггера} [,...n]
Приведем примеры использования триггеров.
Пример 1. Использование триггера для реализации ограничений на значение.
При добавлении записи в таблицу Продажи необходимо учесть следующее:
· значения поля Товар должны быть только такими, какие имеются в таблице Товары;
· значения поля Клиент должны быть только такими, какие имеются в таблице Клиенты;
· количество продаваемого товара должно быть не больше, чем его осталось после всех поставок и предыдущих продаж;
· Дата продажи не должна превышать сегодняшнюю дату.
Команда вставки записи в таблицу Продажи может быть, например, такой: