|
Программирование >> Sql: полное руководство
А вот еще один триггер, который решает проблему иного рода. Он отслеживает попытки удаления из базы данных записей о клиентах, для которых имеются записи о заказах. Обнаружив такую ситуацию, триггер отменяет всю транзакцию, включая инструкцию deleted, в Ответ на которую был вызван триггер: create trigger chK del cust /* триггер, активизирующийся при удалении записи из таблицы COSTOMERS */ on customers for delete as /* Выясняем, имеются ли заказы удаляемого клиента */ if (select count (*) from orderS/ deleted where orders.cust = deleted. cust num) > 0 begin rollback transaction print Удаление невозможно: имеются заказы rdiserror 31234 Для триггеров, связанных с инструкцией update, в Transact-SQL предусмотрена возможность выяснить, какие именно столбцы таблицы были изменены, и в ответ выполнить соответствующие действия. Для этого в триггерах может использоваться специальная форма инструкции if - if update. Следующий триггер активизируется в ответ на обновление записей в таблице salesreps и выполняет различные действия в зависимости от того, какой из столбцов изменен, quota или sales. create trigger upd reps /* триггер, активизирующийсч при обновлении записи в таблице SALESREPS */ on salesreps for update as if update(quota) /* Обрабатываем обновление столбца QUOTA */ If update(sales) /* Обрабатываем обновление столбца SALES */ Триггеры в диалекте Informix в Informix триггеры тоже создаются с помощью инструкции create trigger. Как и в Transact-SQL, эта инструкция определяет имя триггера, таблицу, с которой он связан, и действия, в ответ на которые он выполняется. Вот несколько примеров, иллюстрирующих ее синтаксис: Create trigger new sls insert on salesreps . . . create trigger del cus chk delete on customers . . . create trigger ord upd update on orders . . . create trigger sls upd update of quota, sales on salesreps Последний триггер активизируется только в ответ на обновление заданных столбцов таблицы salesreps. Informix позволяет указать, когда именно должен вызываться создаваемый триггер before - триггер вызывается перед выполнением любых изменений, когда ни одна строка связанной таблицы еще не модифицирована; after - триггер вызывается после выполнения всех изменений, когда все строки связанной таблицы уже модифицированы; for each row - триггер вызывается для каждой модифицируемой строки, и ему доступны как старая, так и новая версия этой строки. Для каждого из этих этапов в триггере может быть задана отдельная последовательность действий. Например, триггер может вызвать хранимую процедуру для вычисления общей стоимости заказов перед обновлением таблицы orders, потом отреагировать на обновление каждой строки, а затем снова вычислить общую стоимость заказов уже после обновления всех требуемых записей. Вот определение триггера, который работает таким образом: create trigger upd ord update of amount on orders referencing old as pre new as post / Вычисляем общую стоимость заказов перед их обновлением */ before (execute procedure add orders() into old total;) /* Отслеживаем увеличение и уменьшение отдельных заказов */ for each row when (post.amount < pre.amount) /* Записываем в отдельную таблицу информацию об уменьшенном заказе */ insert into ord less values (pre.cust, pre.order date, pre.amount, post.amount) when (post.amount > pre.amount) /* Записываем в отдельную таблицу информацию об увеличенном заказе */ insert into ord more values (pre. cust, pre.order date, pre.amount, post.amount) /* После обновления таблицы повторно вычисляем общую стоимость заказов */ after (execute procedure add orders() into new total;) Предложение before в этом триггере указывает на то, что перед тем как начнется выполнение инструкции update, должна быть вызвана хранимая процедура add OR-ders Предполагается, что эта процедура вычисляет общую стоимость заказов, а результат заносится в переменную OLD total. Подобным же образом предложение after определяет, что та же хранимая процедура вызывается по завершении вьтолнения инструкции update И возврашаемое ею значение заносится в другую локальную переменную - new total. Предложение for each row определяет действие, которое должно быть выполнено для каждой обновленной строки таблицы. Таковым в нашем примере является вставка строки в одну из двух таблиц, в зависимости от того, был ли текуший обрабатываемый заказ уменьшен или увеличен Эти таблицы содержат идентификаторы клиентов, даты заказов, а также их старые и новые суммы. Для получения данной информации триггеру нужен доступ к старым (до изменения) и новым (после изменения) значениям строки Предложение referencing задает имена, которые будут использоваться для ссылки на эти две версии текущей строки В нашем примере для ссылки на старые значения столбцов используется псевдоним pre, а для ссылки на новые значения - псевдоним post. Эти имена не являются предопределенными - вы можете назвать таблицы как вам удобно. В отличие от других СУБД, Informix офаничивает набор действий, которые могут выполняться триггером. Допускаются только. инструкция insert; м инструкция delete; инсфукция update; ИНСфуКЦИЯ execute procedure. Впрочем, последняя опция обеспечивает все же некоторую гибкость. Вызванная фиггером процедура может вьшолнять практически любые действия, которые могли бы быть произведены самим фиггером. Триггеры в диалекте Oracle PL/SQL в Oracle возможности создания фиггеров шире, чем в Informix и Transact-SQL В этой СУБД для создания фиггеров тоже используется инструкция create trigger, но структура ее иная. Подобно Informix, она позволяет связать триггер с различными этапами обработки запроса, но на фех разных уровнях Триггер уровня инструкции (statement) вызывается один раз для каждой инструкции SQL. Он может быть вызван до или после ее выполнения. Триггер уровня записи (row) вызывается один раз для каждой модифицируемой записи. Он также может вызываться до или после модификации, Замещающий триггер (instead of) выполняется вместо инсфукции SQL. С помощью такого триггера можно отслеживать попытки приложения или пользователя обновить, добавить или удалить записи и вместо этих действий вьшолнять свои собственные. Вы можете определить фиггер, который должен выполняться вместо некоторой инсфукции или вместо каждой попытки изменения сфоки таблицы. Всего получается 14 различных типов триггеров. Двенадцать из них - это комбинации операций insert, update и delete с опциями before или after на уровне row или statement (3x2x2) плюс еще два фиггера типа instead of уровня row и statement. Однако на практике в реляционных базах данных Oracle триггеры типа instead of применяются редко; они были введены в OracleS для поддержки ее некоторых новейших объектно-ориентированных функций. Ниже даны определения фиггеров в Oracle PL/SQL, которые выполняют ту же роль, что и сложный триггер для Informix из предыдущего парафафа. В Oracle эта задача решается посредством трех триггеров: два из них - это триггеры этапа before и after, действующие на уровне инсфукции, а фетий выполняется для каждой обновляемой строки.
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |