Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ЛР методичка прог в КС / метод_лаб_программирование_КС_071900_2010.doc
Скачиваний:
42
Добавлен:
10.06.2015
Размер:
337.41 Кб
Скачать

Таблицы deleted и inserted

Таблицы deleted и inserted являются специальными представлениями журнала транзакций, доступными лишь во время срабатывания триг­гера и в пределах триггера. В этих таблицах отражаются изменения, внесенные в таблицу командой, которая привела к срабатыванию триггера.

Структуры таблиц inserted и deleted в точности совпадают со структурой таблицы, для которой создавался триггер. Таблица inserted содержит новые записи, созданные командой INSERT или UPDATE. Таблица deleted содержит записи, удаленные вследствие выполнения DELETE или UPDATE.

SQL Server обычно интерпретирует команду UPDETE как DELETE с по­следующей INSERT. Вставляемые и удаляемые записи включаются в таблицы inserted и deleted. Эти таблицы могут использоваться только внутри триггеров для определения того, какое событие вызвало сра­батывание триггера. Записи таблицы inserted создаются при вставке или обновлении, а записи таблицы deleted — при удалении или обнов­лении. Нередко триггер включает таблицы inserted и deleted в объеди­нение для обеспечения ссылочной целостности и целостности внеш­них ключей.

Просмотр таблиц deleted и inserted

В этом разделе приведен пример использования таблиц inserted и deleted. Мы напишем триггер обновления для таблицы publishers, вы­полняющий каскадное удаление в таблице titles.

Не забывайте о проверке количества записей, участвующих в операции (через @@ROWCOUNT), поскольку команда DELETE заставляет триггер сработать ровно один раз, независимо от того, удаляла она записи или нет. Следующий триггер производит каскадное удаление подчинен­ных записей.

Листинг 1. Триггер каскадного удаления

CREATE TRIGGER cascade_del_trigger

ON publisher FOR DELETE

AS

IF @@ROWCOUNT = 0 -- Удаленных записей нет

RETURN

/* Каскадное удаление записей из таблицы titles, */

/* связанных по полю pub_id */

DELETE titles

FROM titles t, deleted d

WHERE t.pub_id = d.pub_id

IF @@ERROR != 0

BEGIN

PRINT 'Error occurred during related tables' ROLLBACK TRAN

END

RETURN

Структура таблиц deleted и inserted идентична структуре базовой таблицы.

Вставка и удаление нескольких записей

SQL Server позволяет вставить несколько записей в одной команде INSERT с помощью конструкции INSERT...SELECT. Если в процессе встав­ки или обновления участвуют несколько значений внешнего ключа, триггер должен сравнить количество вставленных или обновленных записей с количеством записей, являющихся допустимыми ключами. Такое сравнение проверяет, что для модифицированных записей име­ются соответствующие ключи.

Для проверки ссылочной целостности можно воспользоваться агрегатной функцией COUNT(*) для соединения таблицы inserted с таблицей первичного ключа. Например, в начале триггера можно сравнить SELECT COUNT(*) со значением @@ROWCOUNT. Значение @@ROWCOUNT необходимо проверить (а лучше сохранить в локальной переменной) до выполнения в триггере каких-либо операций, способных повлиять на @@ROWCOUNT. Дело в том, что любая команда SQL приводит к измене­нию @@ROWCOUNT (в том числе и та, которая проверяет @@ROWCOUNT).

Следующий фрагмент программы демонстрирует методику проверки ссылочной целостности в триггере:

CREATE TRIGGER tr1

ON...

FOR INSERT, UPDATE

AS

DECLARE @ROWS INT

SELECT @rows = @@ROWCOUNT

IF (SELECT COUNT(*) FROM inserted i, pkey_tab p

WHERE i.fkey = p.pkey) != @rows

/* По крайней мере одна из вставленных/удаляемых записей

** не совпадает с первичным ключом */

/* Начать обработку ошибок */

...Проверка столбцов при модификации

Выполняемая в таблице команда INSERT или UPDATE приводит к сраба­тыванию триггера вставки пли обновления. Если триггер проектировал­ся для обеспечения ссылочной целостности, возможно, вас интересует лишь обновление или вставка в столбцах первичного или внешнего ключа. Конструкция IF UPDATE позволяет определить, выполнялась ли вставка или модификация для конкретного столбца. Синтаксис IF UPDATE выглядит следующим образом:

IF UPDATE (имя_столбца)

[ { AND | OR } UPDATE (,имя_ст6лбца).. ,]

Результат проверки IF UPDATE равен TRUE в случае истинности одного из следующих условий:

• В столбец было вставлено значение, отличное от NULL.

• Столбец был включен в секцию SET команды UPDATE.

Функция COLUMNS_UPDATE() позволяет узнать, входил ли конкретный столбец в команду INSERT или UPDATE. Оператор COLUMNS_UPDATE() имеет следующий синтаксис:

IF (COLUMNS_UPDATE() {поразрядный_оператор} маска_обновления)

{оператор_сравнения} маска_столбцов ]

Проверка может выполняться в триггерах вставки или обновления; с ее помощью можно узнать о факте обновления нескольких столбцов. Параметры имеют следующий смысл:

Поразрядный_оператор — определяет оператор, используемый при сравнении.

Маска_обновления — определяет обновляемые столбцы.

Маска _столбцов — определяет проверяемые столбцы.

Оператор_сравнения — определяет оператор, используемый для проверки столбцов:

= означает, что все столбцы маски должны обновляться.

> означает, что не все столбцы маски должны обновляться.