
- •Московский авиационный институт (Государственный технический университет)
- •Управление базами данных
- •4 Семестр
- •Лекция 1
- •Роль sql
- •Преимущества sql
- •Лекция 2
- •Лекция 3
- •Лекция 4
- •Структура предиката в предложении Where
- •Лекция 5
- •Лекция 6
- •Использование множества таблиц в одном запросе.
- •Лекция 7
- •Лекция 8
- •Представления (View)
- •Создание представлений (инструкция create view)
- •Лекция 9
- •Контроль над обновлением представлений (предложение with check option)
- •Лекция 10
- •Лекция 11
- •Триггеры
- •Лекция 12
- •Лекция 13
- •Лекция 14
- •Управление распределенными базами данных
- •Лекция 15
- •Лекция 16
- •Литература
Триггеры
Триггер — это особая хранимая процедура, которая вызывается в ответ на модификацию содержимого базы данных. В отличие от хранимых процедур, созданных с помощью инструкции create procedure, триггер нельзя выполнить с помощью инструкции call или EXECUTE. Каждый триггер связывается с определенной таблицей базы данных, и СУБД сама выполняет его, когда данные в таблице изменяются инструкцией INSERT, DELETE ИЛИ UPDATE).
Триггеры могут использоваться для автоматического обновления информации в базе данных и поддержания ссылочной целостности в случаях, когда ограничения декларативной ссылочной целостности недостаточны.
Инструкция create trigger используется в большинстве ведущих СУБД для создания нового триггера, включаемого в базу данных. Она назначает триггеру имя, указывает, с какой таблицей его следует связать и в ответ на какие события он должен вызываться. Далее следует тело триггера, которое, как и у обычных хранимых процедур, определяет последовательность инструкций, выполняемых при его вызове.
Контрольные вопросы
Особенности языка SPL в диалекте Watcom-SQL.
Особенности языка SPL в диалекте Transact-SQL.
Особенности оператора CASE в Transact-SQL.
Дайте определения триггера.
Лекция 12
Преимущества и недостатки триггеров
Триггеры, являясь составной частью определения базы данных, могут быть исключительно полезными. Они могут выполнять множество функций, включая следующие:
• Контроль изменений. Триггер может отслеживать и отменять определенные изменения, не разрешаемые в конкретной базе данных.
Каскадные операции. Триггер может отслеживать определенные операции (например, удаление сведений о клиенте или служащем) и автоматически вносить соответствующие изменения в другие таблицы базы данных (допустим, корректировать баланс счетов и объемы продаж).
Поддержка целостности. Триггер может поддерживать более сложные связи между данными, чем те, которые могут быть выражены простыми ограничениями на значения столбцов и условиями ссылочной целостности. Для сохранения этих связей может потребоваться выполнение последовательности инструкций SQL, иногда даже с использованием конструкций IF. . .then. . .ELSE.
Вызов хранимых процедур. В ответ на обновление базы данных триггер может вызвать одну или несколько хранимых процедур и даже выполнить какие-то действия вне базы данных, используя внешние процедуры.
В каждом из этих случаев триггер реализует набор деловых правил, налагаемых на содержимое базы данных. Благодаря тому, что эти правила хранятся в базе данных централизованно (т.е. только в одном месте — в определении триггера) и триггер выполняется в СУБД автоматически, эти правила распространяются на все операции, выполняемые над базой данных ее собственными хранимыми процедурами и всеми внешними приложениями. Если их нужно изменить, достаточно сделать это в одном-единственном месте.
Главным недостатком триггеров является их влияние на производительность операций с базой данных. Если с некоторой таблицей связан триггер, СУБД выполняет его каждый раз, когда эта таблица обновляется. И если от базы данных требуется очень быстрое добавление и модификация больших объемов данных, триггеры могут оказаться неприемлемым решением. Тем более что перед проведением пакетных операций данные могут быть проверены заранее и наверняка будут удовлетворять всем требованиям целостности. По этой причине некоторые СУБД позволяют избирательно активизировать и отключать триггеры по мере необходимости.
Триггеры в диалекте Transact-SQL
В Transact-SQL триггеры создаются инструкцией create trigger (как в Microsoft SQL Server, так и в Sybase Adaptive Server).
Специально для триггеров Transact-SQL определяет две виртуальные таблицы, структура которых идентична структуре таблицы, с которой связан триггер. Эти таблицы называются deleted и inserted. Они заполняются строками из модифицируемой таблицы, причем их конкретное содержимое зависит от выполняемой операции:
delete — все строки, удаленные из связанной таблицы, помещаются в таблицу deleted, таблица inserted пуста;
INSERT — все строки, добавленные в связанную таблицу, помещаются в таблицу inserted, таблица DELETED пуста;
update — для каждой строки связанной таблицы, измененной инструкцией update, ее исходная версия помещается в таблицу deleted, а новая версия — в таблицу inserted.
К этим двум виртуальным таблицам можно обращаться из тела триггера, и их данные можно использовать в триггере наряду с данными всех остальных таблиц.
Для триггеров, связанных с инструкцией UPDATE, в Transact-SQL предусмотрена возможность выяснить, какие именно столбцы таблицы были изменены, и в ответ выполнить соответствующие действия. Для этого в триггерах может использоваться специальная форма инструкции IF — IF update.
Триггеры в диалекте Informix
В Informix триггеры тоже создаются с помощью инструкции create trigger. Как и в Transact-SQL, эта инструкция определяет имя триггера, таблицу, с которой он связан, и действия, в ответ на которые он выполняется.
Informix позволяет указать, когда именно должен вызываться создаваемый триггер
before — триггер вызывается перед выполнением любых изменений, когда ни одна строка связанной таблицы еще не модифицирована;
after — триггер вызывается после выполнения всех изменений, когда все строки связанной таблицы уже модифицированы;
FOR each ROW — триггер вызывается для каждой модифицируемой строки, и ему доступны как старая, так и новая версия этой строки.
Для каждого из этих этапов в триггере может быть задана отдельная последовательность действий.
В отличие от других СУБД, 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 (3x2*2) плюс еще два триггера типа instead of уровня row и statement. Однако на практике в реляционных базах данных Oracle триггеры типа instead OF применяются редко; они были введены в Oracle8 для поддержки ее некоторых новейших объектно-ориентированных функций.
Дополнительные вопросы, связанные с использованием триггеров
В базах данных с триггерами могут быть связаны те же деловые правила, что и с инструкциями update и delete. Например, триггер может вызвать серию каскадных операций. Предположим, что триггер активизируется в ответ на попытку пользователя обновить содержимое таблицы. В теле этого триггера выполняется инструкция update, обновляющая другую таблицу. Триггер этой второй таблицы может обновить еще одну таблицу и т.д. Ситуация ухудшается, когда один из этих триггеров пытается обновить исходную таблицу, обновление которой и вызвало всю серию операций. В этом случае получается бесконечный цикл активизации триггеров.
В различных СУБД эта проблема решается по-разному, в одних системах ограничивается набор действий, которые могут выполняться триггерами. В других предусмотрены встроенные функции, которые позволяют триггеру определить уровень вложенности, на котором он работает. В-третьих, имеются системные установки, определяющие, допустимо ли "каскадирование" триггеров. А есть системы, которые ограничивают уровень вложенности каскадно выполняемых триггеров.
Вторая проблема триггеров состоит в том, что при пакетных операциях с базой данных, например при внесении в нее больших объемов информации, триггеры сильно замедляют работу базы данных. Поэтому некоторые СУБД позволяют избирательно отключать триггеры в таких ситуациях. В Oracle, например, предусмотрена такая форма инструкции alter trigger:
ALTER TRIGGER TEST DISABLE;
Аналогичную возможность обеспечивает инструкция create trigger в Informix.
Рассмотри пример создания триггера в СУБД Sybase SQL Anywhere.
Процедуры и триггеры хранят операторы SQL и управляющие операторы в базе данных для их использования любыми приложениями.
Они улучшают безопасность, эффективность и стандартизацию баз данных.
Пример триггера уровня записи INSERT
Показанный ниже триггер проверяет, что бы дата рождения (birthdate) введенная для нового сотрудника была приемлема.
CREATE TRIGGER check_birth_date
AFTER INSERT ON Employee
REFERENCING NEW AS new_employee
FOR EACH ROW
BEGIN
DECLARE err_user_error EXCEPTION
FOR SQLSTATE ‘99999’;
IF new_employee.birth_date > ‘June 6, 1994’ THEN
SIGNAL err_user_error;
END IF;
END
Триггер вызывается сразу после добавления любой записи в таблицу. Он обнаруживает и не допускает новые записи в которых дата рождения позднее чем 6 июня 1994.
Конструкция REFERENCING NEW AS new_employee позволяет операторам в тексте триггера ссылаться на данные в новой записи используя алиас new_employee.
Для оператора INSERT который добавляет несколько записей в таблицу employee, триггер check_birth_date вызывается для каждой новой записи. Если триггер завершается неудачно хотя бы на одной записи, все изменения сделанные оператором INSERT отменяются.
Можно определить триггер срабатывающий до того как запись будет добавлена, для этого достаточно изменить первую строку примера:
CREATE TRIGGER mytrigger BEFORE INSERT ON Employee
Выражение REFERENCING NEW позволяет ссылаться на значения добавляемой записи; и эта ссылка не зависит от типа триггера (BEFORE or AFTER).
Пример триггера уровня записи для операции DELETE.
CREATE TRIGGER mytrigger BEFORE DELETE ON employee
REFERENCING OLD AS oldtable
FOR EACH ROW
BEGIN
...
END
Выражение REFERENCING OLD позволяет ссылаться в модуле триггера на значения в удаляемой записи с помощью алиаса oldtable.
Триггер легко преобразовать к типу after путем изменения первой строки примера.
CREATE TRIGGER mytrigger BEFORE DELETE ON employee
Выражение REFERENCING OLD не зависит от типа триггера (BEFORE or AFTER).
Пример триггера уровня оператора для операции UPDATE.
CREATE TRIGGER mytrigger AFTER UPDATE ON employee
REFERENCING NEW AS table_after_update
OLD AS table_before_update
FOR EACH STATEMENT
BEGIN
...
END
Выражения REFERENCING NEW и REFERENCING OLD позволяют в тексте триггра ссылаться на старые и новые значения записи, для которой выполняется операция UPDATE. Столбцы с новыми значениями доступны через алиас table_after_update, столбцы со старыми значениями через алиас table_before_update.
Выражения REFERENCING NEW и REFERENCING OLD имеют разный смысл для триггеров уровня оператора и триггеров уровня записи. Для триггеров уровня оператора REFERENCING OLD или NEW являются алиасами таблиц, в триггере уровня записи они ссылаются на изменяемую запись.
Контрольные вопросы
Перечислите преимущества и недостатки триггеров.
Особенности реализации триггеров в Transact-SQL.
Особенности реализации триггеров в СУБД Informix.
Особенности реализации триггеров в Oracle PL/SQL.
Укажите последовательность создания триггера в Sybase Sql Anywhere.