Особенности разработки триггеров и хранимых процедур в СУБД
Федеральное агентство по образованию
Государственное образовательное учреждение
высшего профессионального образования
САРАТОВСКИЙ ГОСУДАРСТВЕННЫЙ УНИВЕРСИТЕТ
ИМЕНИ Н.Г.ЧЕРНЫШЕВСКОГО
Кафедра прикладная информатика
Особенности разработки триггеров и хранимых процедур в СУБД
КУРСОВАЯ РАБОТА
Студентки 4 курса механико-математического факультета 431 группы
заочного отделения
Поликарповой Анны Павловны
Научный руководитель
____________________ ____________________ _____________________
Зав. кафедрой
к. ф.-м. н., доцент_____ ____________________ __С.П.Шевырев________
Саратов 2012 г.
Содержание
ВВЕДЕНИЕ
В данной работе рассмотрим такие объекты Базы данных, как хранимые процедуры. Их виды, свойства, способы реализации, назначения и преимущества. И остановим свое внимание на типе хранимых процедур Триггер. Рассмотрим особенности строения и преимущества данного вида хранимых процедур.
Хранимые процедуры
В этом разделе мы приведём определение, основные свойства и реализацию, а так же назначения и преимущества хранимых процедур.
Хранимая процедура — объект базы данных, представляющий собой набор SQL-инструкций, который компилируется один раз и хранится на сервере. Хранимые процедуры очень похожи на обыкновенные процедуры языков высокого уровня, у них могут быть входные и выходные параметры и локальные переменные, в них могут производиться числовые вычисления и операции над символьными данными, результаты которых могут присваиваться переменным и параметрам. В хранимых процедурах могут выполняться стандартные операции с базами данных (как DDL, так и DML). Кроме того, в хранимых процедурах возможны циклы и ветвления, то есть в них могут использоваться инструкции управления процессом исполнения.
Хранимые процедуры похожи на определяемые пользователем функции (UDF). Основное различие заключается в том, что пользовательские функции можно использовать, как и любое другое выражение в SQL запросе, в то время как хранимые процедуры должны быть вызваны с помощью функции CALL:
CALL процедура(…)
или
EXECUTE процедура(…)
Хранимые процедуры могут возвращать множества результатов, то есть результаты запроса SELECT. Такие множества результатов могут обрабатываться, используя курсоры, другими сохраненными процедурами, возвращая указатель результирующего множества, либо же приложениями. Сохраняемые процедуры могут также содержать объявленные переменные для обработки данных и курсоров, которые позволяют организовать цикл по нескольким строкам в таблице. Стандарт SQL предоставляет для работы выражения IF, LOOP, REPEAT, CASE и многие другие. Сохраняемые процедуры могут принимать переменные, возвращать результаты или изменять переменные и возвращать их, в зависимости от того, где переменная объявлена.
Реализация сохраняемых процедур варьируется от одной СУБД к другой. Большинство крупных поставщиков баз данных поддерживают их в той или иной форме. В зависимости от СУБД, хранимые процедуры могут быть реализованы на различных языках программирования, таких, как SQL, Java, C или C++. Хранимые процедуры, написанные не на SQL, могут самостоятельно выполнять SQL-запросы, а могут и не выполнять. Все более широкое использование хранимые процедур привело к появлению процедурных элементов в языке SQL стандарта SQL:1999 и SQL: 2003 в части SQL/PSM. Это сделало SQL императивным языком программирования. Большинство СУБД предлагают собственные расширения производителя, сверх SQL/PSM.
Реализация хранимых процедур
Хранимые процедуры обычно создаются с помощью языка SQL или конкретной его реализации в выбранной СУБД. Например, для этих целей в СУБД Microsoft SQL Server существует язык Transact-SQL, в Oracle — PL/SQL, в InterBase и Firebird — PSQL, в PostgreSQL — PL/pgSQL, PL/Tcl, PL/Perl, PL/Python, в IBM DB2 — SQL/PL (англ.), в Informix — SPL. MySQL достаточно близко следует стандарту SQL:2003, её язык похож на SQL/PL.
В некоторых СУБД возможно использование хранимых процедур, написанных на любом языке программирования, способном создавать независимые исполняемые файлы, например, на C++ или Delphi. В терминологии Microsoft SQL Server такие процедуры называются расширенными хранимыми процедурами и являются просто функциями, содержащимися в Win32-DLL. А, например, в Interbase и Firebird для функций, вызываемых из DLL/SO, определено другое название — UDF (User Defined Function). В MS SQL 2005 появилась возможность написания хранимых процедур на любом языке .NET, а от расширенных хранимых процедур в будущем планируется отказаться. СУБД Oracle, в свою очередь, допускает написание хранимых процедур на языке Java.[1] В IBM DB2 написание хранимых процедур и функций на обычных языках программирования является традиционным способом, поддерживаемым с самого начала, а процедурное расширение SQL было добавлено в эту СУБД только в достаточно поздних версиях, после его включения в стандарт ANSI. Также процедуры на Java и С поддерживает Informix.
В СУБД Oracle хранимые процедуры могут объединяться в так называемые пакеты (англ. packages). Пакет состоит из двух частей — спецификации (англ. package specification), в которой указывается определение хранимой процедуры, и тела (англ. package body), где находится её реализация. Таким образом Oracle позволяет отделить интерфейс программного кода от его реализации. В СУБД IBM DB2 хранимые процедуры можно объединять в модули.
Назначение и преимущества хранимых процедур
Хранимые процедуры позволяют повысить производительность, расширяют возможности программирования и поддерживают функции безопасности данных.
Вместо хранения часто используемого запроса, клиенты могут ссылаться на соответствующую хранимую процедуру. При вызове хранимой процедуры её содержимое сразу же обрабатывается сервером.
Кроме собственно выполнения запроса, хранимые процедуры позволяют также производить вычисления и манипуляцию данными — изменение, удаление, выполнять DDL-операторы (не во всех СУБД!) и вызывать другие хранимые процедуры, выполнять сложную транзакционную логику. Один-единственный оператор позволяет вызвать сложный сценарий, который содержится в хранимой процедуре, что позволяет избежать пересылки через сеть сотен команд и, в особенности, необходимости передачи больших объёмов данных с клиента на сервер.
В большинстве СУБД при первом запуске хранимой процедуры она компилируется (выполняется синтаксический анализ и генерируется план доступа к данным). В дальнейшем её обработка осуществляется быстрее. В СУБД Oracle выполняется интерпретация хранимого процедурного кода, сохраняемого в словаре данных. Начиная с версии Oracle 10g поддерживается так называемая естественная компиляция (native compilation) хранимого процедурного кода в С и затем в машинный код целевой машины, после чего при вызове хранимой процедуры происходит прямое выполнение её скомпилированного объектного кода.
Возможности программирования
Созданную хранимую процедуру можно вызвать в любой момент, что обеспечивает модульность и стимулирует повторное использование кода. Последнее облегчает сопровождение базы данных, так как она становится изолированной от меняющихся бизнес-правил. Модифицировать хранимую процедуру в соответствии с новыми правилами можно в любой момент. После этого все приложения, использующие её, автоматически придут в соответствие с новыми бизнес-правилами без непосредственной модификации.
Безопасность
Использование хранимых процедур позволяет ограничить или вообще исключить непосредственный доступ пользователей к таблицам базы данных, оставив пользователям только разрешения на выполнение хранимых процедур, обеспечивающих косвенный и строго регламентированный доступ к данным. Кроме того, некоторые СУБД поддерживают шифрование текста (wrapping) хранимой процедуры.
Эти функции безопасности позволяют изолировать от пользователя структуру базы данных, что обеспечивает целостность и надежность базы.
Снижается вероятность таких действий как «внедрение SQL-кода», поскольку хорошо написанные хранимые процедуры дополнительно проверяют входные параметры перед тем, как передать запрос СУБД.
Триггеры
В данном разделе рассмотрим триггеры базы данных - процедуры, которые хранятся в базе данных и неявно исполняются ("возбуждаются"), когда модифицируется ассоциированная таблица. Подробно рассмотрим создание, отладку, изменение, удаление, включение и выключение триггеров для систем, которые используют ORACLE с процедурной опцией.
Триггер (англ. trigger) — это хранимая процедура особого типа, которую пользователь не вызывает непосредственно, а исполнение которой обусловлено действием по модификации данных: добавлением INSERT, удалением DELETE строки в заданной таблице, или изменением UPDATE данных в определенном столбце заданной таблицы реляционной базы данных. Триггеры применяются для обеспечения целостности данных и реализации сложной бизнес-логики. Триггер запускается сервером автоматически при попытке изменения данных в таблице, с которой он связан. Все производимые им модификации данных рассматриваются как выполняемые в транзакции, в которой выполнено действие, вызвавшее срабатывание триггера. Соответственно, в случае обнаружения ошибки или нарушения целостности данных может произойти откат этой транзакции.
Момент запуска триггера определяется с помощью ключевых слов BEFORE (триггер запускается до выполнения связанного с ним события; например, до добавления записи) или AFTER (после события). В случае, если триггер вызывается до события, он может внести изменения в модифицируемую событием запись (конечно, при условии, что событие — не удаление записи). Некоторые СУБД накладывают ограничения на операторы, которые могут быть использованы в триггере (например, может быть запрещено вносить изменения в таблицу, на которой «висит» триггер, и т. п.)
Кроме того, триггеры могут быть привязаны не к таблице, а к представлению (VIEW). В этом случае с их помощью реализуется механизм «обновляемого представления». В этом случае ключевые слова BEFORE и AFTER влияют лишь на последовательность вызова триггеров, так как собственно событие (удаление, вставка или обновление) не происходит.
В некоторых серверах триггеры могут вызываться не для каждой модифицируемой записи, а один раз на изменение таблицы. Такие триггеры называются табличными.
Проектирование триггеров
Триггеры используются для того, чтобы гарантировать, что при выполнении определенной операции, будут выполнены связанные с ней действия также триггеры базы используются данных только для глобальных, централизованных операций, которые должны быть выполнены для соответствующего предложения (предложения триггера), независимо от того, какой пользователь или приложение базы данных выдает это предложение.
Так как триггер должен быть откомпилирован, когда он возбуждается впервые (а также при последующих возбуждениях, если он был вытеснен из своей разделяемой области контекста), хорошей идеей является ограничение размера триггеров (приблизительно 60 строками). Компиляция триггеров меньшего размера не окажет существенного влияния на производительность системы. Если триггер должен исполняться многократно, предпочтительно включить код, исполняемый таким триггером, в хранимую процедуру (которая хранится в откомпилированной форме). В этом случае триггер будет вызывать откомпилированную хранимую процедуру, избегая затрат времени на компиляцию.
Создание триггеров
Триггеры создаются с помощью команды REATE TRIGGER. Эту команду можно использовать в любом интерактивном инструменте (таком как SQL*Plus или SQL*DBA); при использовании в таких инструментах, одиночная наклонная черта ("/"), вводимая как последняя строка, обозначает конец предложения CREATE TRIGGER. Следующее предложение создает триггер, ассоциированный с таблицей EMP:
CREATE TRIGGER dummy
BEFORE DELETE OR INSERT OR UPDATE ON emp
FOR EACH ROW
WHEN (new.empno > 0)
DECLARE
/* переменные, константы, курсоры и т.п. */
BEGIN
/* блок PL/SQL */
END;
Предложение CREATE собьется, если в блоке PL/SQL будут обнаружены ошибки.
Последующие секции будут использовать этот пример, чтобы проиллюстрировать способы, которыми специфицируются различные части триггера.
Предварительные условия
Прежде чем создавать любые триггеры, необходимо выполнить скрипт CATPROC.SQL под учетным именем SYS. Этот скрипт автоматически запускает все скрипты, которые необходимы для процедурной опции или используются этой опцией. Местоположение этого файла зависит от операционной системы.
Именование триггеров
Имена триггеров должны быть уникальными среди всех триггеров в той же схеме. Имена триггеров не обязаны быть уникальными по отношению к другим объектам схемы (таких как таблицы, обзоры, процедуры); например, таблица и триггер могут иметь одно и то же имя (хотя, во избежание путаницы, это не рекомендуется).
Опции BEFORE/AFTER
Либо опция BEFORE, либо опция AFTER должна быть указана в предложении CREATE TRIGGER, чтобы точно специфицировать, когда должно исполняться тело триггера по отношению к исполнению предложения триггера. В предложении CREATE TRIGGER опция BEFORE или AFTER задается непосредственно перед ключевым словом, обозначающим предложение триггера. Например, триггер DUMMY, который был определен в предыдущем примере, является триггером BEFORE.
Триггеры строк AFTER несколько более эффективны, чем триггеры строк BEFORE. При триггерах строк BEFORE, затрагиваемые блоки данных должны быть считаны (логической, а не физической, операцией чтения) один раз для триггера и еще один раз для предложения триггера. Альтернативно, при триггерах строк AFTER, затрагиваемые блоки данных должны быть считаны лишь один раз, сразу для предложения триггера и для самого триггера.
Предложение триггера
Предложение триггера специфицирует:
- Тип предложения SQL, которое возбуждает тело триггера. Допустимыми возможностями являются DELETE, INSERT и UPDATE. В спецификацию предложения триггера могут быть включены одна, две или все три этих опции.
- Таблицу, ассоциированную с триггером. Заметим, что в предложении триггера может быть специфицирована ровно одна таблица (но не обзор).
Например, предложениями, возбуждающими триггер DUMMY, являются любые предложения DELETE, INSERT или UPDATE по таблице EMP. Любое из следующих предложений возбудит триггер DUMMY, показанный в предыдущем примере:
DELETE FROM emp;
INSERT INTO emp VALUES ( . . . );
INSERT INTO emp SELECT . . . FROM . . . ;
UPDATE emp SET . . . ;
Список столбцов для UPDATE
Если предложение триггера специфицирует UPDATE, то в эту спецификацию может быть включен необязательный список столбцов. Если включить список столбцов, то данный триггер возбуждается по предложению UPDATE лишь тогда, когда это предложение обновляет один из перечисленных столбцов. Если вы опускаете список столбцов, то триггер возбуждается при обновлении любого столбца ассоциированной таблицы. Список столбцов не может быть специфицирован для предложений триггера INSERT или DELETE.
Предыдущий пример определения триггера DUMMY мог бы содержать список столбцов для предложения триггера, например:
. . . BEFORE DELETE OR INSERT OR UPDATE OF ename ON emp . . .
Опция FOR EACH ROW
Присутствие или отсутствие опции FOR EACH ROW определяет, является ли этот триггер триггером предложения или триггером строки. Если эта опция включена, она указывает, что тело триггера возбуждается отдельно для каждой строки таблицы, предложением триггера. Отсутствие опции FOR EACH ROW указывает, что данный триггер должен возбуждаться лишь один раз для предложения триггера.
Фраза WHEN
В определение триггера строки может быть включено необязательное ограничение триггера, путем специфицирования булевского выражения SQL в фразе WHEN (фраза WHEN не может быть включена в определение триггера предложения). Выражение в фразе WHEN, если эта фраза присутствует, вычисляется для каждой строки, затрагиваемой триггером. Если результат выражения дает TRUE для строки, то тело триггера исполняется для этой строки. Однако, если это выражение вычисляется для строки как FALSE или NULL, то тело триггера не исполняется для этой строки. Вычисление условия фразы WHEN не влияет на исполнение самого предложения триггера (т.е. предложение триггера НЕ откатывается, если выражение в фразе WHERE вычисляется как FALSE).
Например, для триггера DUMMY, тело триггера не исполняется, если новое значение столбца EMPNO нулевое, отрицательное или NULL. В более реалистичных примерах вы могли бы проверять, скажем, чтобы одно значение столбца было меньше другого. Выражение в фразе WHEN для триггера строки может включать корреляционные имена, которые объясняются ниже. выражение в фразе WHEN должно быть выражением SQL (но не выражением PL/SQL), и не может включать подзапрос.
Тело триггера
Тело триггера - это блок PL/SQL, который может содержать предложения SQL и PL/SQL. Эти предложения исполняются тогда, когда выдано предложение триггера, и ограничение триггера (если оно есть) вычислено как TRUE. Для триггеров строк тело триггера имеет некоторые специальные конструкты, которые могут быть включены в код этого блока PL/SQL: корреляционные имена, опцию REFERENCING, а также условные предикаты INSERTING, DELETING и UPDATING.
Доступ к значениям столбцов в триггерах строки
Внутри тела триггера строк, код PL/SQL и предложения SQL имеют доступ как к старым, так и к новым значениям столбцов текущей строки, затрагиваемой предложением триггера. Для каждого столбца модифицируемой таблицы определены два КОРРЕЛЯЦИОННЫХ ИМЕНИ: одно для старого (old), другое - для нового значения столбца (new). В зависимости от типа предложения триггера, то или иное корреляционное имя может быть лишено смысла.
- Триггер, возбужденный предложением INSERT, имеет осмысленный доступ лишь к новым значениям столбцов. Поскольку строка создается предложением INSERT, старые значения столбцов пусты (NULL).
- Триггер, возбужденный предложением UPDATE, имеет доступ как к старым, так и к новым значениям столбцов для обоих возможных типов триггера (BEFORE или AFTER).
- Триггер, возбужденный предложением DELETE, имеет осмысленный доступ лишь к старым значениям столбцов. Поскольку строка перестает существовать после ее удаления, новые значения столбцов пусты (NULL). Новые значения столбцов адресуются квалификатором NEW перед именем столбца, старые - квалификатором OLD. Например, если предложение триггера ассоциировано с таблицей EMP, содержащей столбцы SAL, COMM и т.д., то вы можете включить в тело триггера предложения, подобные следующим:
IF :new.sal > 10000 . . .
IF :new.sal < :old.sal . . .
Старые и новые значения доступны как в триггерах BEFORE, так и в триггерах AFTER. Назначать новое значение столбца можно в триггере строк BEFORE, но не в триггере строк AFTER (потому что предложение триггера уже выполнено, прежде чем триггер AFTER получает управление). Если триггер строк BEFORE изменяет NEW для столбца, то триггер AFTER, возбужденный тем же самым предложением, видит значение, которое было назначено триггером BEFORE.
Корреляционные имена могут также использоваться в булевском выражении фразы WHEN. Заметьте, что перед квалификаторами OLD и NEW должно кодироваться двоеточие, когда они используются в теле триггера, но двоеточие не допускается, когда эти квалификаторы используются в фразе WHEN или опции REFERENCING.
Опция REFERENCING
Опция REFERENCING может специфицироваться в теле триггера строк для того, чтобы избежать конфликтов между корреляционными именами и именами таблиц, в случае, если таблица имеет имя "OLD" или "NEW". Поскольку такая ситуация редка, эта опция почти никогда не применяется. Например, предположим, что у вас есть таблица с именем NEW, содержащая столбцы FIELD1 (числовой) и FIELD2 (символьный).
Следующее предложение CREATE TRIGGER показывает триггер, ассоциированный с таблицей NEW, который использует опцию REFERENCING, чтобы избежать конфликтов между корреляционными именами и именем таблицы:
CREATE TRIGGER dummy
BEFORE UPDATE ON new
REFERENCING new AS newest
FOR EACH ROW
BEGIN
:newest.field2 := TO_CHAR (:newest.field1);
END;
Заметим, как квалификатор NEW переименован в NEWEST с помощью опции REFERENCING, а затем использован в теле триггера.
Условные предикаты
Если триггер может быть возбужден более чем одним типом предложения DML (например, "INSERT OR DELETE OR UPDATE OF emp"), в теле триггера можно использовать условные предикаты INSERTING, DELETING и UPDATING, для того чтобы выполнять различные участки кода в зависимости от типа предложения, возбудившего триггер. Предположим, что предложение триггера определено следующим образом:
INSERT OR UPDATE ON emp
В коде внутри тела триггера вы можете использовать следующие условия:
IF INSERTING THEN . . . END IF;
IF UPDATING THEN . . . END IF;
Первое условие будет вычисляться как TRUE лишь в тех случаях, когда триггер был возбужден предложением INSERT; второе условие будет вычисляться как TRUE лишь в тех случаях, когда триггер был возбужден предложением UPDATE. Кроме того, в триггере UPDATE условный предикат UPDATING можно специфицировать перед именем столбца, чтобы определять, обновляется ли этот столбец текущим предложением, возбудившим триггер. Например, предположим, что триггер определен следующим образом:
CREATE TRIGGER . . .
. . . UPDATE OF sal, comm ON emp . . .
BEGIN
. . . IF UPDATING ('SAL') THEN . . . END IF;
END;
Код в фразе THEN выполняется лишь в том случае, если предложение UPDATE, возбудившее триггер, обновляет столбец SAL. Например, предложение возбудит показанный выше триггер и заставит условный предикат вычислиться как TRUE:
UPDATE emp SET sal = sal + 100;
Условия ошибок и исключения в теле триггера
Если во время исполнения тела триггера возникает условие или определенной пользователем ошибки (исключение), то все действия как тела триггера, так и предложения, возбудившего триггер, откатываются (если это исключение не обрабатывается специально). Поэтому тело триггера может сознательно воспрепятствовать исполнению предложения триггера путем возбуждения исключения.
Обычно в триггерах используются определяемые пользователем исключения, которые реализуют комплексные проверки полномочий или ограничения целостности.
Ограничения на создание триггеров
Следующие секции обсуждают ограничения, которые налагаются на триггеры.
Число триггеров на таблицу. Лишь один триггер каждого типа может существовать на таблицу. Это позволяет иметь для таблицы двенадцать возможных триггеров:
BEFORE UPDATE строк AFTER UPDATE строк
BEFORE DELETE строк AFTER DELETE строк
BEFORE INSERT предложения AFTER INSERT предложения
BEFORE INSERT строк AFTER INSERT строк
BEFORE UPDATE предложения AFTER UPDATE предложения
BEFORE DELETE предложения AFTER DELETE предложения
Если вы попытаетесь повторно создать любой тип триггера, уже существующий для таблицы, вы получите ошибку времени компиляции.
Замечание: Каждая таблица может иметь до четырех триггеров UPDATE (BEFORE/AFTER, предложения/строки), независимо от того, возбуждаются ли эти триггеры при обновлении специфических столбцов.
Допустимые предложения SQL в теле триггера. Тело триггера может любые предложения DML, включая предложения SELECT (только SELECT ... INTO или предложения SELECT в определениях курсоров), INSERT, UPDATE и DELETE; в теле триггера не допускаются предложения DDL. Нельзя также управлять транзакциями в контексте триггера. Поэтому внутри контекста тела триггера не допускаются следующие предложения: ROLLBACK, COMMIT и SAVEPOINT.
Замечание: Процедура, вызываемая из триггера, также не может выполнять перечисленных выше предложений управления транзакциями, ибо такая процедура исполняется внутри контекста тела триггера.
Предложения внутри триггера могут адресоваться к удаленным объектам. Однако будьте особенно внимательны, вызывая удаленные процедуры из локального триггера; если во время выполнения триггера будет обнаружено несовпадение отметок времени, то удаленная процедура не выполняется, а триггер станет недействительным.
Типы данных LONG и LONG RAW в триггере. Следующие правила объясняют особенности использования типов данных LONG и LONG RAW внутри триггеров:
- Предложение SQL внутри триггера может вставлять данные в столбец типа данных LONG или LONG RAW.
- Если данные из столбца LONG или LONG RAW могут быть преобразованы в ограниченный тип данных (такой как CHAR или VARCHAR2), то к такому столбцу LONG или LONG RAW можно обращаться в предложении SQL внутри триггера.
Заметим, что максимальная длина для этих типов данных равна 32K.
- Нельзя объявлять переменные с типом данных LONG или LONG RAW.
- Нельзя использовать квалификаторы :NEW и :OLD со столбцами LONG и LONG RAW.
Таблицы с журналами снимков. Создание журнала снимков неявно создает триггер AFTER ROW по главной таблице. Поэтому нельзя пользовательский триггер AFTER ROW по главной таблице, имеющей журнал снимков. И наоборот, если для таблицы определен триггер AFTER ROW, то для этой таблицы нельзя создать журнал снимков; необходимо сначала удалить этот триггер. Снимки и журналы снимков обсуждаются в главе 12.
Ссылки на пакетированные переменные. Если предложение UPDATE или DELETE обнаруживает конфликт с конкурирующей операцией UPDATE, то ORACLE выполняет прозрачный откат к точке сохранения и повторно запускает обновление. Это может повториться, пока предложение не выполнится успешно. Каждый раз, когда предложение перезапускается, ассоциированный триггер предложения снова возбуждается. Откат к точке сохранения не отменяет изменений в любых пакетированных переменных, адресуемых в этом триггере. Соответствующий пакет должен включать переменную-счетчик, чтобы распознавать такую ситуацию.
Порядок вычисления строк. Реляционная база данных не гарантирует определенности порядка строк, обрабатываемых предложением SQL. Поэтому не создавайте триггеров, которые от того, в каком порядке будут обрабатываться строки. Например, не назначайте значения глобальной пакетированной переменной в триггере строк, если это текущее значение зависит того, какая строка сейчас обрабатывается триггером строк. Кроме того, если в триггере обновляются глобальные пакетированные переменные, лучше всего инициализировать такие переменные в триггере предложения BEFORE.
Если предложение в теле триггера вызывает возбуждение другого, этот эффект называется КАСКАДОМ ТРИГГЕРОВ. ORACLE позволяет иметь одновременно до 32 каскадно возбужденных триггеров. Однако вы можете по существу ограничить количество каскадных триггеров через параметр инициализации MAX_OPEN_CURSORS; для каждого исполнения триггера должен открываться курсор.
Мутирующие и ограничивающие таблицы. Мутирующая таблица – это таблица, модифицируемая в данный момент предложением UPDATE, или INSERT, или таблица, которая может потребовать обновления в результате действия декларативного ссылочного ограничения целостности DELETE CASCADE. Ограничивающая таблица - это таблица, которую предложение, возбуждающее триггер или ограничение, должно читать, - либо явно (для предложения SQL), неявно (для декларативного ограничения ссылочной). Мутирующая или ограничивающая таблица является таковой лишь для той сессии, которая выдает предложение, возбуждающее триггер или ограничение.
Для триггеров предложений таблица не рассматривается как мутирующая или как ограничивающая; однако для триггеров строк имеют место два важных ограничения, касающихся мутирующих и ограничивающих таблиц:
- Предложения в триггере строк не могут читать или модифицировать мутирующую таблицу предложения триггера. Это ограничение не позволяет триггеру строк иметь дело с несогласованным множеством данных.
- Предложения в триггере строк не могут изменять столбцов первичного, внешнего или уникального ключа ограничивающей таблицы предложения триггера. Это ограничение введено с тем, чтобы успех предложения внутри триггера не зависело от порядка обработки строк или от индекса.
Для этого правила существует одно исключение: триггер BEFORE ROW, возбужденный предложением INSERT, вставляющим одиночную строку в таблицу с внешним ключом, может модифицировать любые столбцы первичной таблицы, пока эта модификация не нарушает никаких ограничений целостности.
Если необходимо обновить мутирующую или ограничивающую таблицу, вам следует использовать временную таблицу, таблицу PL/SQL или пакетированную переменную, чтобы обойти эти ограничения.
Декларативные ограничения целостности проверяются в различные моменты времени по отношению к триггерам строк; обратитесь к документу ORACLE7 Server Concepts Manual за информацией о том, как взаимодействуют триггеры и ограничения целостности.
Привилегии, требуемые для создания триггеров
Чтобы создать триггер в своей схеме, вы должны иметь системную привилегию CREATE TRIGGER, а также одно из:
Владеть таблицей, специфицированной в предложении триггера, или иметь привилегию ALTER для таблицы, специфицированной в предложении триггера, или иметь системную привилегию ALTER ANY TABLE

- Особенности разработки туристического продукта предприятием отрасли туризма (на примере ООО «Интерлайн»)
- Особенности разработки туров (на примере экологического туризма)
- Особенности разработки управленческих решений в условиях неопределенности
- Особенности разработки управленческого решения в рекламной деятельности предприятия
- Особенности разрешения конфликтно-педагогических ситуаций студентами
- Особенности разрешения конфликтов на примере компании ООО «Практика»
- Особенности раскрытие похищение человека
- Особенности разработки концепции реструктуризации предприятия
- Особенности разработки концепции реструктуризации предприятия
- Особенности разработки маркетингового комплекса предприятия при работе на внешних рынках
- Особенности разработки меню
- Особенности разработки Приобского месторождения
- Особенности разработки программы чрезвычайной стабилизации
- Особенности разработки стратегий для малого бизнеса