Главная » SQL, Базы данных » ТРИГГЕРЫ (НЕБОЛЬШОЕ ОТСТУПЛЕНИЕ)

0

Из всего сказанного выше в данной главе должно быть очевидно, что для нас особый интерес представляет декларативная поддержка целостности. И хотя ситуация за последние годы улучшилась, остается фактом, что лишь немногие продукты (если они вообще есть) обеспечивают такую поддержку со времени своего первоначального появления на рынке. Вследствие этого ограничения целостности чаще всего реализуются процедурное использованием триггерных процедур. Последние представляют собой заранее откомпилированные процедуры, которые хранятся вместе с базой данных (возможно, в самой базе  данных) и вызываются автоматически при возникновении некоторых указанных событий. В частности, пример 1 ("значения статуса должны находиться в пределах от 1 до 100 включительно") может быть реализован с помощью триггерной процедуры, которая вызывается каждый раз при вставке кортежа в переменную отношения S, проверяет этот вновь вставляемый кортеж и снова его удаляет, если значение статуса не входит в указанные пределы. В этом разделе приведено краткое описание триггерных процедур в связи с тем, что они имеют значительную практическую важность. Но необходимо сразу же привести следующие замечания.

1.            Именно потому, что они являются процедурами, триггерные процедуры  нельзя считать рекомендуемым способом реализации ограничений целостности. Пользователям сложнее понять, как действуют процедуры, а для системы процедуры создают дополнительные трудности при оптимизации. Следует также отметить, что декларативные ограничения проверяются при всех соответствующих обновлениях18, а триггерные процедуры выполняются только при возникновении указанного события (допустим, при вставке кортежа в переменную отношения S).

2.  Область применения триггерных процедур не ограничивается задачами поддержки целостности, которые являются темой настоящей главы. Вместо этого, если учесть замечания, сделанные в п. 1, фактически они могут выполнять другие полезные задачи и именно поэтому имеют право на существование. Некоторые примеры таких "других полезных задач" приведены ниже.

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

б)  Отладка (т.е. отслеживание ссылок на указанные переменные и/или контроль над изменениями состояния этих переменных).

в)  Аудит (например, регистрация информации о том, кто и когда внес те или иные изменения в определенные переменные отношения).

г)   Измерение производительности (например, регистрация времени наступления или трассировка указанных событий в базе данных).

д)  Проведение компенсирующих действий (например, каскадная организация удаления кортежа поставщика для удаления также соответствующих кортежей поставок)19.

Поэтому данный раздел, как и указано в его названии, носит характер отступления от основной темы.

Рассмотрим следующий пример. (Этот пример основан на языке SQL, а не на языке Tutorial D, поскольку в [3.3] не предписана, и не могла быть предписана какая-либо поддержка триггерных процедур; фактически он основан на  коммерческом программном продукте, а не на стандарте SQL, поскольку стандарт SQL не поддерживает конкретное средство, показанное в данном примере.) Предположим, что в базе данных имеется представление LONDON_SUPPLIER, которое определено следующим образом.

CREATE VIEW LONDON_SUPPLIER AS SELECT S#, SNAME,

STATUS FROM  S WHERE CITY = ‘London’ ;

При обычных обстоятельствах, если пользователь попытается вставить строку в это представление, то среда поддержки языка SQL действительно вставит строку в соответствующую базовую таблицу S с таким значением CITY, которое задано по умолчанию для

18 Обратите внимание на то, что в спецификациях декларативных ограничений не предусмотрены явные указания для СУБД, когда должны выполняться проверки целостности. А это и не требуется, вопервых, потому, что такие явные указания вынуждали бы пользователя, объявляющего ограничения, вы полнять лишнюю работу, во-вторых, потому, что пользователь мог бы их задать неправильно. Вместо этого желательно, чтобы сама система решала, когда должны проводиться эти проверки (см. аннотацию к [9.5]).

19 И действительно, каскадное удаление — это типичный пример триггерной процедуры. Но заслу живает внимания то, что такое удаление задано декларативно! Автор отнюдь не утверждает, что ссылоч ные действия — это неудачная идея только потому, что они реализуются "триггерно" (т.е. как реакция на некоторое событие).

столбца CITY (см. главу 10). При условии, что по умолчанию задан город, отличный от Лондона общий эффект этого действия окажется таким, что новая строка не появится в этом представлении! Поэтому создадим триггерную процедуру следующим образом.

CREATE TRIGGER LONDON_SUPPLIER_INSERT INSTEAD OF INSERT ON LONDON_SUPPLIER REFERENCING NEW ROW AS R

FOR EACH ROW

INSERT INTO S ( S#, SNAME, STATUS, CITY )

VALUES ( R.S#, R.SNAME, R.STATUS, ‘London’ ) ;

Теперь вставка строки в это представление повлечет за собой то, что строка будет вставлена в соответствующую базовую таблицу со значением CITY, равным London, а не  со  значением,  применяемом  по  умолчанию  (и   новая   строка  теперь  будет появляться в представлении, в полном соответствии с поставленной задачей).

Из этого примера следуют определенные выводы, приведенные ниже.  Примечание. Эти выводы не относятся только к языку SQL, несмотря на тот факт, что приведенный пример основан на SQL (конкретные сведения о  средствах SQL даны в следующем разделе).

1.          В общем, в операторе создания триггера CREATE TRIGGER, кроме всего прочего,

определены событие, условие и действие следующим образом:

■      событием является операция в базе данных (в этом примеое "INSERT   ON LONDON_SUPPLIER");

■      условие— это логическое выражение, которое должно принимать значение TRUE для того, чтобы было выполнено действие (если условие не указано явно, как в данном примере, то оно по умолчанию равно npocто TRUE);

■      действие — это и есть сама триггерная процедура (в данном примере "INSERT

INTO  S  …").

Событие и условие вместе иногда называют триггерным событием, а  сочетание всех трех компонентов (событие, условие и действие) обычно называют просто триггером. По очевидным   причинам   триггеры   именуются   также    правилами   "событие-условиедействие" (Event-Condition-Action — ЕСА) или сокращенно правилами ЕСА.

2.          К возможным событиям относится выполнение операций INSERT, DELETE, UPDATE (возможно, над определенными атрибутами), достижение конца транзак ций (COMMIT), наступление указанного времени суток, истечение определенного интервала времени, нарушение указанного ограничения и т.д.

3.          В общем, действие может выполняться до (BEFORE), после (AFTER) или вместо (INSTEAD OF) действия, обусловленного указанным событием, при условии, что эти варианты имеют смысл.

4.          В общем, действие может выполняться для каждой строки (FOR EACH ROW) или для каждого оператора (FOR EACH STATEMENT), при условии, что эти варианты имеют смысл.

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

6.            Базу данных, которая имеет связанные с ней триггеры, иногда называют активной базой данных.

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

■     Если одно и то же событие вызывает запуск (как принято называть это событие на профессиональном жаргоне) нескольких разных триггеров, то последовательность их активизации может оказаться, с одной стороны, важной, а с другой — неопре деленной.

■     Могут возникать цепочки запуска триггеров, при которой запуск триггера Т1 вызы вает активизацию триггера Т2, который вызывает активизацию триггера ТЗ и т.д.

■     Запуск триггера т может даже снова вызвать рекурсивный запуск самого этого триггера.

■     В результате наличия триггеров даже "простые" операции INSERT,  DELETE  или UPDATE могут приводить к такому эффекту, который принципиально отличается от ожидаемого пользователем (особенно если задано ключевое слово INSTEAD OF, как в приведенном выше примере).

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

 

Источник: Дейт К. Дж., Введение в системы баз данных, 8-е издание.: Пер. с англ. — М.: Издательский дом «Вильямс», 2005. — 1328 с.: ил. — Парал. тит. англ.

По теме:

  • Комментарии