Триггеры oracle. Триггеры ORACLE FORMS для начинающих

В 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

DECLARE err_user_error EXCEPTION

FOR SQLSTATE ‘99999’;

IF new_employee.birth_date > ‘June 6, 1994’ THEN

SIGNAL err_user_error;

Триггер вызывается сразу после добавления любой записи в таблицу. Он обнаруживает и не допускает новые записи в которых дата рождения позднее чем 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.

REFERENCING OLD AS oldtable

Выражение 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

Выражения REFERENCING NEW и REFERENCING OLD позволяют в тексте триггра ссылаться на старые и новые значения записи, для которой выполняется операция UPDATE. Столбцы с новыми значениями доступны через алиас table_after_update, столбцы со старыми значениями через алиас table_before_update.

Выражения REFERENCING NEW и REFERENCING OLD имеют разный смысл для триггеров уровня оператора и триггеров уровня записи. Для триггеров уровня оператора REFERENCING OLD или NEW являются алиасами таблиц, в триггере уровня записи они ссылаются на изменяемую запись.

Контрольные вопросы

1. Перечислите преимущества и недостатки триггеров.

2. Особенности реализации триггеров в Transact-SQL.

3. Особенности реализации триггеров в СУБД Informix.

4. Особенности реализации триггеров в Oracle PL/SQL.

5. Укажите последовательность создания триггера в Sybase Sql Anywhere.

Лекция 13

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

Когда срабатывают INSERT, UPDATE, или DELETE триггеры, порядок выполнения операций следующий:

1 Выполняется какой-либо BEFORE триггер.

2 Выполняются действия определенные правилами ссылочной целостности.

3 Выполняется соответствующая операция.

4 Выполняются триггеры типа AFTER.

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

Интерфейсы взаимодействия с БД

Функции SQL/CLI и их группировка

Структура протокола ODBC

Функции ODBC и расширенные возможности ODBC.

Протокол ODBC и стандарт SQL/CLI

ODBC (Open Database Connectivity - открытый доступ к базам данных) – это разработанный компанией Microsoft универсальный программный интерфейс для доступа к базам данных. Хотя в современном компьютерном мире Microsoft играет важную роль как производитель программного обеспечения для баз данных, все же в первую очередь, она один из ведущих производителей операционных систем, именно это послужило мотивом создания ODBC: Microsoft захотела облегчит разработчикам приложений Windows доступ к базам данных. Все дело в том, что различные СУБД существенно отличаются друг от друга, как и их программные интерфейсы. Если разработчику нужно было написать приложение, работающее с базами данных нескольких СУБД, для каждой из них приходилось писать отдельный интерфейсный модуль (обычно называемый драйвером). Чтобы избавить программистов от выполнения одной и той же рутинной и достаточно сложной работы, Microsoft решила на уровне операционной системы стандартизировать интерфейс взаимодействия между приложениями и СУБД, благодаря чему во всех программах мог бы использоваться один и тот же универсальный набор функций, поддерживаемый всеми производителями СУБД. Таким образом, от внедрения ODBC выиграли и разработчики приложений, и производители СУБД, для которых также решалась проблема совместимости.

Формирование стандарта SQL/CLI

Даже если бы протокол ODBC был всего лишь собственным стандартом компании Microsoft, его значение все равно было бы очень велико. Однако Microsol постаралась сделать его независимым от конкретной СУБД. Одновременно ассоциация производителей СУБД (SQL Access Group) работала над стандартизацией протоколов удаленного доступа к базам данных в архитектуре клиент/сервер. Microsoft убедила ассоциацию принять ODBC в качестве независимого стандарта доступа базам данных. В дальнейшем этот стандарт перешел в ведение другой организации, Европейского консорциума Х/Open, и был включен в ее комплект стандартов САЕ (Common Application Environment - единая прикладная среда).

С ростом популярности программных интерфейсов доступа к базам данных организации, ответственные за принятие официальных стандартов, стали уделять этому аспекту SQL все более пристальное внимание. На основе стандарта Х/Open (базировавшегося на ной версии ODBC, разработанной компанией Microsoft) с небольшими модификациями - был разработан официальный стандарт ANSI/ISO. Этот стандарт, известный SQL/CLI (SQL/Call Level Interface - интерфейс уровня вызовов функций), был опубликован в 1995 году под названием ANSI/ISO/IEC 9075-3-1995. Он представляет собой Часть 3 разрабатываемого многоуровневого стандарта SQL3, который является развитием опубликованного в 1992 году стандарта SQL2.

Microsoft привела ODBC в соответствие со стандартом SQL/CLI, реализация которого составляет ядро последней версии ее протокола - ODBC 3. Однако полный набор высокоуровневых функций ODBC 3 выходит далеко за рамки спецификации CLI: он предоставляет разработчикам приложений гораздо более широкие возможности и решает ряд специфических задач, связанных с использованием ODBC как части операционной системы Windows.

Преимущества связки ODBC/CLI как для разработчиков приложений, так и для производителей СУБД были настолько очевидны, что оба стандарта очень быстро получили самую широкую поддержку. Практически все производители реляционных СУБД включили в свои продукты соответствующие интерфейсы. ODBC и CLI Поддерживаются тысячами приложений, включая ведущие пакеты инструментальных средств разработки.

Стандартом SQL/CLI определяется около сорока функций (см. табл.). Они служат подключения к серверу баз данных, выполнения инструкций SQL, обработки результатов запросов, а также обработки ошибок, произошедших в ходе выполнения инструкций. Эти функции обеспечивают полный набор возможностей, предоставляемых встроенным SQL, включая как статический, так и динамический SQL.

Функции SQL/CLI

Функция Описание

Управление ресурсами и подключением к базе данных

SQLAllocHandle() Выделяет ресурсы для среды SQL; сеанса подключения к базе данных, описателя CLI или инструкции

SQLFreeHandle () Освобождает ранее выделенные ресурсы

SQLAllocEnv () Выделяет ресурсы для среды SQL

SQLFreeEnv () Освобождает ресурсы, выделенные для среды SQL

SQLAllocConnect () Выделяет ресурсы для сеанса подключения к базе данных

SQLFreeConnect () Освобождает ресурсы, выделенные для сеанса подключения к базе данных

SQLAllocstmt () Выделяет ресурсы для инструкции SQL

SQLFreeStmt() Освобождает ресурсы, выделенные для инструкции SQL

SQLConnect () Устанавливает соединение с базой данных

SQLDisconnect() Разрывает соединение с базой данных

Выполнение инструкций SQL

SQLExecDirect() Непосредственно выполняет инструкцию SQL

SQLPrepare() Подготавливает инструкцию SQL к последующему выполнению SQLExecute() Выполняет ранее подготовленную инструкцию SQL

SQLRowCount() Возвращает количество строк, обработанных последней инструкци­ей SQL

Управление транзакциями

SQLEndTran() Завершает или отменяет транзакцию

SQLCancel() Отменяет выполнение текущей инструкции SQL

Обработка параметров

SQLBindParam() Связывает параметр инструкции SQL с адресом программного буфера

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

SQLPutData() Предоставляет данные для параметра подготавливаемой инструкции; эта функция может вызываться многократно, чтобы передавать данные по частям

Обработка результатов запроса

SQLSetCursorName() Назначает имя набору записей

SQLGetCursorName() Возвращает имя набора записей

SQLBindCol() Связывает столбец в таблице результатов запроса с программным буфером

SQLFetch() Возвращает следующую строку из таблицы результатов запроса SQLFetchScroll() Возвращает указанную строку из таблицы результатов запроса SQLCloseCursor() Закрывает набор записей

SQLGetData() Возвращает значение указанного столбца из таблицы результатов запроса

Описание результатов запроса

SQLNumResultCols() Возвращает количество столбцов в таблице результатов запроса

SQLDescribeCol() Возвращает описание указанного столбца в таблице результатов запроса

SQLColAttribute() Возвращает информацию об указанном атрибуте заданного столбца в таблице результатов запроса

SQLGetDescField() Возвращает значение указанного поля из описателя CLI SQLSetDescField() Устанавливает значение указанного поля в описателе CLI SQLGetDescRec() Возвращает значения набора полей из описателя CLI SQLSetDescRec() Устанавливает значения набора полей в описателе CLI

SQLCopyDesc() Копирует содержимое одного описателя CLI в другой

Обработка ошибок

SQLError() Возвращает информацию об ошибке, произошедшей во время последнего вызова функции CL1

SQLGetDiagField() Возвращает значение указанного поля из специальной структуры CLI, содержащей диагностическую информацию

SQLGetDiagRec() Возвращает значения набора полей из специальной структуры CLI, содержащей диагностическую информацию

Управление атрибутами

SQLSetEnvAttr() Устанавливает значение указанного атрибута среды SQL SQLGetEnvAttr() Возвращает значение указанного атрибута среды SQL

SQLSetConnectAttr() Устанавливает значение указанного атрибута сеанса подключения к базе данных

SQLGetConnectAttr() Возвращает значение указанного атрибута сеанса подключения к базе данных

SQLSetStmtAttr() Устанавливает значение указанного атрибута инструкции SQL SQLGetStmtAttr() Возвращает значение указанного атрибута инструкции SQL

Управление драйвером

SQLDataSources() Возвращает список доступных серверов баз данных

SQLGetFunctions() Возвращает информацию о функциях CLI, поддерживаемых теку­щим драйвером

SQLGetlnfо() Возвращает общую информацию об источнике данных и драйвере, которые связаны с указанным сеансом подключения к базе данных

SQLGetTypelnfо() Возвращает информацию о поддерживаемых типах данных

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

Программа подключается к библиотеке CLI и выделяет память под структуры данных, используемые функциями этой библиотеки;

Программа подключается к конкретному серверу баз данных;

Программа формирует инструкции SQL в собственных буферах памяти;

Программа вызывает функции CLI, с помощью которых она просит сервер выполнить инструкции SQL и узнает о завершении этих инструкций;

В случае успешного выполнения инструкций SQL программа с помощью еще одной функции CLI просит сервер завершить транзакцию;

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

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

Протокол ODBC. Структура ODBC.

Структура протокола ODBC изображена на рис. Программное обеспечение ODBC состоит из трех основных уровней:

Интерфейс вызовов функций. На самом верхнем уровне ODBC находится единый программный интерфейс, который может использоваться всеми приложениями. Этот API реализован в виде библиотеки динамической компоновки (DLL), которая является неотъемлемой частью Windows.

Драйверы ODBC. На нижнем уровне располагается набор драйверов: по одному драйверу для каждой поддерживаемой СУБД. Задачей драйвера является трансляция стандартных вызовов функций ODBC в вызовы соответствующих функций, поддерживаемых конкретной СУБД (их может быть и несколько для одной функции ODBC). Каждый драйвер устанавливается в операционной системе независимо. Это позволяет производителям СУБД разрабатывать для своих продуктов собственные драйверы и распространять их независимо от Microsoft. Если СУБД располагается в той же системе, что и драйвер ODBC, то драйвер обычно напрямую вызывает внутренние API-функции СУБД. Если же доступ к базе данных осуществляется: по сети, то драйвер может: а) направлять все вызовы в клиентскую часть СУБД; которая будет переадресовывать их на сервер; б) самостоятельно управлять сеансом сетевого подключения к удаленной базе данных.

Диспетчер драйверов. Средний уровень занят диспетчером драйверов ODBC, который отвечает за загрузку и выгрузку драйверов по запросам приложений, а также за направление вызовов функций ODBC, производимых приложениями соответствующим драйверам для выполнения.

Когда приложению нужно получить доступ к базе данных посредством ODBC оно выполняет ту же самую последовательность начальных действий, которая предусматривается стандартом SQL/CLI. Прежде всего, программа получает дескрипторы среды и сеанса, а затем вызывает функцию SQLConnect(), указав конкретный источник данных, с которым она хочет работать. В ответ на это диспетчер драйверов ODBC анализирует переданную программой информацию о подключении и определяет, какой драйвер ей нужен. Диспетчер загружает этот драйвер в память, если только к настоящему времени драйвер не используется никакой другой программой. Все последующие вызовы функций в пределах данного сеанса обрабатываются этим драйвером. Программа может затем вызывать функцию SQLConnect() для подключения к другим источникам данных, что вызовет загрузку дополнительных драйверов; но, тем не менее, обращения к различным базам данных и различным СУБД будут производиться посредством единого набора функций.

Независимое взаимодействие сразличными СУБД

Разработав универсальный программный интерфейс и многоуровневую архитектуру ODBC с диспетчеризацией вызовов, Microsoft значительно продвинулась в направлении независимого от СУБД доступа к базам данных, но сделать доступ абсолютно "прозрачным" вряд ли возможно. Драйверы ODBC для различных СУБД могут легко замаскировать незначительные отличия их программных интерфейсов и диалектов SQL, но более фундаментальные отличия скрыть трудно или даже невозможно. ODBC частично решает эту проблему, разделяя полный набор предлагаемых возможностей на несколько функциональных уровней и вводя набор функций, позволяющих драйверу ODBC "рассказать" о себе приложению: предоставить ему информацию о своих возможностях, наборе поддерживаемых функций и типов данных. Однако само наличие нескольких уровней функциональных возможностей драйверов и выборочная поддержка драйверами этих возможностей ставит приложение в зависимость от СУБД, хотя и на другом уровне. Поэтому на практике большинство приложений использует только базовые функции ODBC.

Контрольные вопросы

1. Определите назначение протокола ODBC.

2. Перечислите группы функций входящие в протокола ODBC.

3. Опишите структуру ODBC.

4. Сформулируйте преимущества использования ODBC.

Лекция 14

Функции ODBC для работы с системными каталогами.

Одной из областей, в которых ODBC предлагает возможности, выходящие за рамки стандарта SQL/CLI, является получение информации о структуре базы данных из системного каталога.

Стандарт ODBC не считает обязательным наличие в базе данных информационной схемы.

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

Функции ODBC, предназначенные для работы с системными каталогами, обычно не нужны в специализированных приложениях, а вот программам общего назначения, таким как модули формирования запросов, генераторы отчетов и утилиты анализа данных, без подобных функций обойтись. Эти функции можно вызывать в любое время после подключения к источнику данных. Например, генератор отчетов может вызвать функцию SQLConnect() и сразу же вслед за ней - функцию SQLTables(), чтобы узнать, какие таблицы имеются в базе данных.

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

Функции ODBC, предназначенные для работы с системным каталогами

Функция Описание

SQLTables() Возвращает список таблиц заданного каталога (каталогов) и схемы (схем)

SQLTablePrivileges () Возвращает список привилегий заданной таблицы (таблиц)

SQLColumns() Возвращает список имен столбцов заданной таблицы (таблиц)

SQLColumnPrivileges() Возвращает список привилегий на указанные столбцы заданной таблицы

SQLPrimaryKeys() Возвращает список имен столбцов, составляющих первичный ключ заданной таблицы

SQLForeignKeys() Возвращает список внешних ключей заданной таблицы и список внешних ключей других таблиц, которые связаны с заданной таблицей

SQLSpecialColumns() Возвращает список столбцов, которые однозначно идентифицируют строку таблицы, или столбцов, которые автоматически обновляются при обновлении строки

SQLStatistics() Возвращает статистические данные о таблице и ее индексах

SQLProcedures() Возвращает список хранимых процедур заданного источника данных

SQLProcedureColumns() Возвращает список входных и выходных параметров и имена возвращаемых столбцов для заданной хранимой процедуры (процедур)

Расширенные возможности ODBC

Как уже упоминалось, ODBC предоставляет дополнительные возможности помимо тех, что определены стандартом SQL/CLI. Многие из них предназначены, для повышения производительности приложений, использующих ODBC, за счет минимизации количества вызовов функций ODBC, необходимых для выполнения типичных задач, а также за счет сокращения сетевого трафика при работе с ODBC. Кроме того, ODBC предоставляет ряд возможностей, обеспечивающих большую независимость приложения от конкретной СУБД и помогающих приложению устанавливать соединение с источником данных. Часть дополнительных возможностей ODBC реализована в виде функций, показанных ниже. Остальные управляются атрибутами инструкций и сеансов. Многие из расширенных возможностей ODBC появились в версии 3.0 этого протокола и еще не все драйвера их поддерживают.

Некоторые дополнительные функции ODBC

Функция Описание

SQLBrowseConnect() Возвращает информацию об атрибутах указанного источника данных ODBC, которые необходимо задать для подключения к источнику

SQLDrivers() Возвращает список доступных драйверов и имен их атрибутов

SQLDriverConnect() Расширенная форма функции SQLConnect(), предназначенная для передачи ODBC дополнительной информации о сеансе подключения

SQLNumParams() Возвращает количество параметров последней подготовленной инструкции SQL

SQLBindParameter() Дополняет возможности функции SQLBindParam() SQLDescribeParam() Возвращает информацию о параметре инструкции SQL

SQLBulkOperations() Выполняет пакетные операции с использованием механизма закладок

SQLMoreResults() Определяет, остались ли еще необработанные записи в таблице результатов запроса

SQLSetPos() Задает позицию указателя в результирующем наборе записей, разрешая приложению выполнять позиционные операции над этим набором

SQLNativeSQL() Возвращает перевод заданной инструкции SQL на “родной” диалект SQL той СУБД, с которой ведется работа

Функция Параметры Действие
SQLCONNECT() DataSourceName – имя источника данных, cUserID – имя пользователя, cPassword | cConnectionName]) – пароль или имя соединения Устанавливает соединение с указанным источником данных ODBC. Возвращает положительное целое число в случае успеха, -1 – при неудаче.
SQLSETPROP(nConnectionHandle, cSetting [, eExpression]) nConnectionHandle – указатель на соединение с источником данных полученный от Sqlconnect(), cSetting – имя параметра, eExpression – значение параметра; Возможные значения для cSetting Asynchronous BatchMode ConnectBusy ConnectString ConnectTimeOut DataSource DispLogin DispWarnings IdleTimeout ODBChdbc ODBChstmt PacketSize Password QueryTimeOut Transactions WaitTime Для заданного соединения с источником данных устанавливает значения различных параметров.
SQLEXEC(nConnectionHandle, ]) nConnectionHandle – указатель на соединение с источником данных полученный от Sqlconnect(), cSQLCommand – оператор SQL передаваемый источнику данных, CursorName – имя курсора куда будет помещен результат, по умолчанию- SQLRESULT.
SQLPREPARE(nConnectionHandle, cSQLCommand, ) SQLEXECUTE(nConnectionHandle, cSQLCommand, ) Подготавливает оператор SQL к выполнению функцией SQLEXEC()
SQLGETPROP(nConnectionHandle, cSetting) Возвращает текущие значения или значения по умолчанию для активного соединения.
SQLSTRINGCONNECT() Устанавливает соединение с источником данных через строку соединения
SQLCOMMIT(nConnectionHandle) Завершает транзакцию
SQLROLLBACK(nConnectionHandle) Отменяет любые изменения сделанные в текущей транзакции
SQLMORERESULTS(nConnectionHandle) Копирует следующий набор данных в курсор VFP (если такой набор данных существует)
SQLDISCONNECT(nConnectionHandle)
SQLCANCEL(nConnectionHandle) Прерывает выполнение текущего SQL оператора.
SQLTABLES(nConnectionHandle [, cTableTypes] [, cCursorName]) Сохраняет имена таблиц в источнике данных в курсор VFP
SQLCOLUMNS(nConnectionHandle, TableName [, “FOXPRO” | “NATIVE”] [, CursorName]) Сохраняет список имен столбцов и информацию о каждом столбце таблицы в источнике данных в курсор VFP

Управление сеансами

Две из расширенных возможностей ODBC связаны с организацией сеансов. Механизм просмотра информации о подключении предназначен для упрощения процесса подключения к источнику данных. В основе этого механизма лежит функция SQLBrowseConnect(). Сначала приложение вызывает эту функцию, указывая имя источника данных, и в ответ получает описание необходимых для подключения атрибутов (таких как имя пользователя и пароль). Программа собирает нужную информацию (например, запросив ее у пользователя) и передает ее функции SqlBrowseConnect(), которая возвращает описание последующих атрибутов. Цикл одолжается до тех пор, пока приложение не предоставит ODBC всю информацию, обходимую для подключения к заданному источнику данных. Как только это будет сделано, соединение будет установлено.

Механизм группировки подключений предназначен для более эффективного управления процессами установления/разрыва соединения в среде клиент/сервер. Когда режим группировки подключений активизирован, ODBC, получив вызов функции SQLDisconnect(), не завершает сеанс подключения. Он остается в неактивном состоянии в течение некоторого времени, и если за это время поступит новый вызов функции SQLConnect(), ODBC просто активизирует имеющееся подключение (если, конечно, приложению нужен тот же источник данных). Повторное использование подключений позволяет существенно снизить расходы, связанные с многократным входом в серверную систему (и последующим выходом из нее) в приложениях, выполняющих большое число коротких транзакций.

Summary : in this tutorial, you will learn about another named PL/SQL block called an Oracle trigger. You will also learn about different characters of triggers and their usage in the database.

What is an Oracle trigger

A trigger is a named PL/SQL block stored in the Oracle database and executed implicitly when a triggering event takes place. The event can be any of the following:

  • A data manipulation language statement executed against a table e.g., or . For example, if you define a trigger to fire before an INSERT statement on the customers table, this trigger fires each time before you insert a new row into the customers table.
  • A data definition language statement e.g., or statement executed. These triggers are often used for auditing purposes to record changes of the schema.
  • A system event such as startup or shutdown of the Oracle database.
  • A user event such as login or logout.

The act of executing a trigger is also known as firing a trigger. We say the trigger is fired.

Oracle trigger usages

Oracle triggers are useful in many cases such as the following:

  • Enforcing complex business rules that cannot be established using integrity constraint such as , NOT NULL , etc.
  • Preventing invalid transactions.
  • Gathering statistical information on table accesses.
  • Generating value automatically for derived columns.
  • Auditing sensitive data.

How to create a trigger in Oracle

To create a new trigger in Oracle, you use the following CREATE TRIGGER statement:

DECLARE

declarationstatements

BEGIN

executablestatements

EXCEPTION

exception_handlingstatements

END ;

Let’s examine the syntax of the CREATE TRIGGER statement in more detail.

A trigger has two main parts: header and body. The following is the trigger header:

CREATE TRIGGER trigger_name

{BEFORE |AFTER }triggering_eventON table_name

And here is the trigger body:

DECLARE

declarationstatements

BEGIN

executablestatements

EXCEPTION

exception_handlingstatements

END ;

As you can see the trigger body has the same structure as an .

1) CREATE OR REPLACE

The CREATE keyword specifies that you are creating a new trigger. The OR REPLACE keywords are optional. They are used to modify an existing trigger. Even though the OR REPLACE keywords are optional, they appear with the CREATE keyword in most cases.

For example, if today you define a new trigger named trigger_example:

CREATE TRIGGER trigger_example

And in a few days, you decide to modify this trigger. If you do not include the OR REPLACE keywords like:

Then you will receive an error message states that the name of your trigger is already used by another object.

So the CREATE OR REPLACE statement

CREATE OR REPLACE trigger_example

will create a new trigger if the trigger does not exist or replace the existing trigger.

2) Trigger name

Following the CREATE OR REPLACE keywords is the name of the trigger.

3) BEFORE | AFTER

The BEFORE or AFTER option specifies when the trigger fires, either before or after a triggering event e.g., INSERT , UPDATE , or DELETE

The table_name is the name of table associated with the trigger.

4) FOR EACH ROW

The clause FOR EACH ROW specifies that a trigger is row-level trigger and fires once for each row inserted, updated, or deleted.

Note that you will learn about statement-level triggers in the subsequent tutorial.

5) ENABLE / DISABLE

The ENABLE / DISABLE option specifies whether the trigger is created in the enabled or disabled state. Note that if a trigger is disabled, it is not fired when the triggering event occurs.

By default, if you don’t specify ENABLE / DISABLE statement, the trigger is created with the enabled state.

6) FOLLOWS | PRECEDES another_trigger

For each triggering event e.g., INSERT , UPDATE , or DELETE , you can define multiple triggers to fire. In this case, you need to specify the firing sequence using the FOLLOWS or PRECEDES option.

Let’s create a trigger to see understand how it works.

Creating an Oracle trigger example

Suppose we want to record actions against the customers table whenever a row is updated or deleted. In order to do this, first, we for recording the UPDATE and DELETE events:

CREATE TABLE audits(

audit_idNUMBER generatedBY DEFAULT AS identityPRIMARY KEY ,

table_nameVARCHAR2 (255),

transaction_nameVARCHAR2 (10),

by_userVARCHAR2 (30),

transaction_dateDATE

Second, we create a new trigger associated with the customers table:

CREATE OR REPLACE TRIGGER customer_audit

AFTER UPDATE OR DELETE ON customers

DECLARE

v_transactionVARCHAR2 (10);

BEGIN

Determine the transaction typ

v_transaction:=CASE

WHEN UPDATINGTHEN "UPDATE"

WHEN DELETINGTHEN "DELETE"

END ;

Insert a row into the audit table

INSERT INTO audits(table_name,transaction_name,by_user,transaction_date)

VALUES ("CUSTOMERS" ,v_transaction,USER ,SYSDATE );

Триггеры уровня DML Триггер уровня DML является объектом реляционной базы данных (специальный вид хранимой процедуры), который активизирует выполнение хранимой (или встроенной) PL/SQL процедуры при изменении пользователем данных в таблице. Событие, управляющее запуском триггера, описывается в виде логических условий. Например, попытка модифицировать данные в таблице активизирует триггер, соответствующий данной команде манипулирования данными. Число триггеров на таблицу базы данных не ограничено. Обычно триггеры используют для реализации ограничений ссылочной целостности, для предотвращения несогласованных изменений в базе данных (поддержка целостности базы данных), для выполнения скрытых операций при модификации, а также для снижения сетевого трафика за счет передачи обработки на сервер. Операции завершения транзакции выполняются после обработки триггеров.

Триггеры уровня DML Триггер уровня DML является объектом реляционной базы данных (специальный вид хранимой процедуры), который активизирует выполнение хранимой (или встроенной) PL/SQL процедуры при изменении пользователем данных в таблице. Событие, управляющее запуском триггера, описывается в виде логических условий. Например, попытка модифицировать данные в таблице активизирует триггер, соответствующий данной команде манипулирования данными. Число триггеров на таблицу базы данных не ограничено. Oracle поддерживает три вида триггеров: предваряющие (BEFORE), замещающие (INSTEAD OF) и завершающие (AFTER). Как и логично было бы ожидать, предваряющие триггеры вызываются перед обработ кой запроса на вставку, обновление или удаление, замещающие вместо него, а завершающие после обработки запроса. Всего имеется девять воз можных типов триггеров: предваряющий триггер вставки, обновления и удаления, замещающий триггер вставки, обновления и удаления и завер шающий триггер вставки, обновления и удаления. Обычно триггеры используют для реализации ограничений ссылочной целостности, для предотвращения несогласованных изменений в базе данных (поддержка целостности базы данных), для выполнения скрытых операций при модификации, а также для снижения сетевого трафика за счет передачи обработки на сервер. Операции завершения транзакции выполняются после обработки триггеров.

Триггеры уровня DML При выполнении команды UPDATE с помощью триггера можно проверить, что модифицируемые данные удовлетворяют ограничениям целостности базы данных до выполнения операции (при этом возможен доступ к новым данным!). После выполнения операции с помощью триггера можно выполнить скрытую обработку данных с учетом поступивших изменений (старые данные также могут быть доступны). При выполнении команды INSERT также можно проверить данные до вставки в таблицу на допустимость ограничениям целостности, а после выполнить операции над только что вставленными данными. При выполнении команды DELETE можно проверить данные до их удаления или восстановить данные после удаления. .

Синтаксис команды CREATE TRIGGER Для создания триггера предусмотрена специальная команда SQL CREATE TPIGGER. Эта команда создает триггер на таблице, которой владеет пользователь. CREATE TRIGGER [имя схемы. ]имя триггера {BEFORE|AFTER} {INSERT|DELETE|UPDATE ]} ]}] ON [имя схемы. ]имя таблицы BEGIN … END

Синтаксис команды CREATE TRIGGER Ключевое слово OR REPLACE указывает на безусловное замещение старого теста триггера. Если оно не указывается, а триггер определен в базе данных, то замещения старого триггера не происходит, и возвращается сообщение об ошибке. Определение триггера состоит из нескольких частей: * задание имени триггера; * указание команды SQL, к которой относится триггер; * указание таблицы или представления, для которой определяется триггер; * задание ограничений триггера; * задание действия в теле триггера. Если имя схемы опущено, то триггер создается в схеме текущего пользователя.

Синтаксис команды CREATE TRIGGER {BEFORE|AFTER} время действия триггера до или после выполнения команды манипулирования данными. Нельзя определить два триггера на одну и ту же операцию с одинаковым временем действия. При создании триггера необходимо указывать, к какой команде манипулирования данными он относится INSERT, DELETE или UPDATE. Для последней можно указывать конкретные колонки, указав фразу OF имя_колонки [, имя_колонки. . . ] в предложении UPDATE. Ключевое слово ON задает имя таблицы или представления, для которого создается триггер. Необязательное ключевое слово ON EACH ROW определяет триггер как строчный, т. е. запускаемый для каждой строки результирующего множества команды SQL. Если оно опущено, то триггер запускается только один раз в начале обработки команды. Таким образом, условие "для каждой строки" активизируется, только когда есть строки (например, предложение WHERE дает истинное значение условий поиска), в то время как для условия "для каждой команды" триггер сработает и в этом случае. Дополнительные условия, сужающие область действия триггера, могут быть заданы в предложении WHEN. Условия, задаваемые в этом предложении, являются стандартными для SQL условиями, должны содержать корреляционные имена и не могут содержать запрос. Это предложение может быть указано только для строчного триггера.

Участие в транзакциях По умолчанию триггеры DML принимают участие в транзакциях, из которых они запускаются, т. е. : Если триггер инициирует исключение, то соответствующая часть транзакции будет отменена. Если триггер сам выполняет какие то операторы DML (например, вставляет запись в журнальную таблицу), то такие операторы DML становятся частью главной транзакции. Внутри триггера DML нельзя использовать операторы COMMIT и ROLLBACK. Если использовать триггер DML как автономную транзакцию, то любые команды DML, исполняемые внутри триггера, будут сохранены или отменены посредством явно использованного оператора COMMIT или ROLLBACK, при этом главная транзакция затрагиваться не будет

Псевдозаписи NEW и OLD При запуске триггера уровня строки исполняющее ядро PL/SQL создаёт и заполняет две структуры данных, которые работают подобно записям. Это псевдозаписи NEW и OLD (приставка «псевдо» объясняется тем, что они обладают не всеми свойствами настоящих записей PL/SQL). OLD хранит начальные значения записи, обрабатываемой триггером, а NEW - новые значения. Эти записи имеют такую же структуру, как запись, объявленная при помощи атрибута %ROWTYPE на основе таблицы, к которой относится триггер. Правила при работе с псевдозаписями NEW и OLD: Для триггеров, относящихся к командам INSERT, структура OLD не содержит никаких данных, «старого» набора значений не существует. Для триггеров, относящихся к командам DELETE, структура NEW не содержит никаких данных, т. к. речь идёт об удалении записи. Изменение значений полей структуры OLD запрещено, попытка такого изменения приведёт к возникновению ошибки ORA 04085. Изменение значений полей структуры NEW допустимо.

Псевдозаписи NEW и OLD Структура NEW Или OLD не может передаваться как параметр типа запись в процедуру или функцию, вызываемую внутри триггера. Можно передавать только отдельные поля псевдозаписей. gentrigrec. sp программа, формирующая код, который передаёт значения NEW и OLD записям, которые уже могут передаваться как параметры. При ссылке на структуру NEW или OLD внутри анонимного блока триггера необходимо предварять двоеточием соответствующие ключевые слова, например: IF: NEW. salary > 10000 THEN. . . Выполнение операций уровня записи для структур NEW и OLD не поддерживается. Например, подобный код вызовет ошибку при компиляции триггера: BEGIN: NEW: = NULL; END;

Псевдозаписи NEW и OLD Активизирующий оператор: OLD: NEW INSERT Не определена, во всех полях содержится NULL значения Значения, которые будут введены после выполнения оператора. UPDATE Исходные значения, содержащиеся в строке перед обновлением данных Новые значения, которые будут введены после выполнения оператора DELETE Исходные значения, содержащиеся в строке перед ее удалением Не определена, во всех полях содержится NULL значения

Пример 1 создания триггера Использование триггеров вводимых данных для проверки допустимости Предположим, у галереи (см. описание практического примера в гл. 1) есть правило, что ни одна работа не может быть продана менее, чем за 90% от запрошенной цены. Чтобы обеспечить выполнение этого правила, можно написать триггер обновления для таблицы TRANSACTION, срав нивающий значения Asking. Price и Sales. Price. Если правило нарушается, в столбец Asking. Price ставится исходное значение. Можно использовать две стратегии. Одна заключается в том, чтобы написать предваряющий триггер, который проверяет и переустанавлива ет, если необходимо, значение столбца Sales. Price до выполнения обновле ния. Вторая стратегия - написать завершающий триггер, проверяющий и переписывающий строку таблицы TRANSACTION после обновления.

Пример 1 создания триггера CREATE OR REPLACE TRIGGER TRANS_Sales. Price. Check BEFORE UPDATE ON TRANSACTION FOR EACH ROW BEGIN IF: new. Sales. Price

Пример 1 создания триггера Логика работы триггера: Если новая продажная цена состав ляетменее 90% от запрашиваемой цены, продажная цена устанавливается равной запрашиваемой цене. Новая продажная цена сравнивается со старой запрашиваемой ценой; в противном случае можно было бы, изменив обе цены, успешно совершить обновление, нару шающееданное ограничение. На тот случай, если именно так и произо шло, столбец Asking. Price в операторе UPDATE устанавливается равным: old. Asking. Price. Этот триггер будет вызываться рекурсивно. Оператор UPDATE в триггере вызовет обновление таблицы TRANSACTION, что, в свою очередь, приведет к повторному вызову триг гера. На этот раз, однако, столбец Sales. Price будет равен: old. Asking. Price, поэтому новых обновлений произведено не будет и рекурсия остановится.

Пример 2 создания триггера Использование триггеров для присвоения значений по умолчанию Столбцам таблицы могут присваиваться значения по умолчанию с по мощью квалификатора DEFAULT. В качестве таких значений можно за давать константы или результаты вычисления простых выражений. Если же задание значения по умолчанию требует более сложной логики, необ ходимо использовать триггер. Предположим, что у галереи имеется прави ло, согласно которому запрашиваемая цена произведения устанавливается равной удвоенной стоимости его приобретения или сумме общей стоимо стиприобретения и чистой выручки от продажи этого произведения в прошлом. Это правило реализуется с помощью завершающего триггера.

Пример 2 создания триггера Представление, которое используется в рас сматриваемом триггере, имеет следующий вид: CREATE VIEW Artist. Work. Net AS SELECT W. Work. ID, Name, Title, Copy, Acquisition. Price, Sales. Price, (Sales. Price Acqisition. Price) AS Net. Price FROM TRANSACTION T JOIN WORK W ON T. Work. ID = W. Work. ID JOIN ARTIST A ON W. Artist. ID = A. Artist. ID;

Пример 2 создания триггера CREATE OR REPLACE TRIGGER Set. Asking. Price BEFORE INSERT ON TRANSACTION FOR EACH ROW DECLARE avg. Net. Price numeric(8, 2); new. Price numeric(8, 2); rowcount integer; BEGIN SELECT Count(*) INTO rowcount FROM TRANSACTION WHERE Work. ID = : new. Work. ID; IF rowcount = 0 THEN: new. Asking. Price: = 2*(: new. Acquisition. Price); ELSE SELECT AVG(Net. Price) INTO avg. Net. Price FROM Artist. Work. Net AW WHERE AW. Work. ID = : new. Work. ID GROUP BY AW. Work. ID; new. Price: = avg. Net. Price + : new. Acquisition. Price; IF new. Price > 2*(: new. Acquisition. Price) THEN: new. Asking. Price: = new. Price; ELSE: new. Asking. Price: = 2*(: new. Acquisition. Price); END IF; END;

Пример 2 создания триггера Триггер сначала подсчитывает количество строк в таблице TRANSACTION, в которых значение Work. ID равно: new. Work. ID. По скольку это предваряющий триггер, произведение еще не добавлено в базу данных, и количество будет равным нулю, если это произведение не появ лялось в галерее ранее. В этом случае: new. Asking. Price устанавливается равным удвоенному значению Acquisition. Price. Если произведение появлялось в галерее в прошлом, рассчитывает сясредняя чистая прибыль от его продажи с помощью представле ния Artist. Work. Net. После этого вычисляется переменная new. Price как сумма средней чистой прибыли и стоимости приобретения. Наконец, : new. Asking. Price присваивается большее из двух значений - new. Price или удвоенное значение Acquisition. Price. Так как триггер предваряющий, для усреднения можно использовать встроенную функцию AVG: новая стро каеще не добавлена в таблицу WORK, поэтому она не будет учтена при расчете среднего значения. Если в какой либо из строк представления Artist. Work. Net столбец Sales. Price или Acquisition. Price явля ется пустым, это может вызвать проблемы при вычислениях в триггере.

Пример 3 создания триггера Триггер, обновляющий представление Обновление представлений в ряде случаев может оказаться затрудни тельным. Одна из таких проблем касается представлений, созданных при помощи операции соединения. Рассмотрим представление Customerlnterests: CREATE VIEW Customer. Interests AS SELECT С. Name AS Customer, A. Name AS Artist FROM CUSTOMER С JOIN CUSTOMER_ARTIST_INT C 1 ON С. Customerl. D = C 1. Customerl. D JOIN ARTIST A ON C 1. Artist. ID = A. Artist. ID; Оно содержит строки таблиц CUSTOMER и ARTIST, соединенные через таблицу пересечения. Столбцу CUSTOMER. Name дан псевдоним Customer, а столбцу ARTIST. Name - Artist.

Пример 3 создания триггера Запрос на изменение имени клиента в представлении Customerlnterests можно интерпретировать как запрос на изменение столбца Name в таб лице CUSTOMER. Такой запрос может быть обработан лишь в том случае, если это имя является уникальным в таблице CUSTOMER. В противном случае невозможно будет определить, какую из строк следует обновлять. Замещающий триггер обнов ляетимя клиента, если это имя является уникальным в базе данных. Вме стотого чтобы подсчитывать количество строк с данным именем клиента и выполнять обновление только в том случае, если такая строка всего одна, триггер обусловливает обновление ключевым словом NOT EXISTS. Такая конструкция триггера позволяет Oracle оптимизировать SQL оператор и приводит к лучшей производительности. CREATE OR REPLACE TRIGGER Customerlnterests. JJpdate INSTEAD OF UPDATE ON Customerlnterests FOR EACH ROW BEGIN UPDATE CUSTOMER C 1 SET C 1. Name = : new. Customer WHERE C 1. Name = : old. Customer AND NOT EXISTS (SELECT * FROM CUSTOMER C 2 WHERE C 2. Name = C 1. Name AND C 2. Customerl. D C 1. Customerl. D); END;

Определение DML действия внутри триггера Oracle предлагает набор функций (называемых также операционными директивами), которые позволяют определить, какое DML действие вызвало запуск текущего триггера. Каждая такая функция возвращает TRUE или FALSE. INSERTING Возвращает TRUE, если триггер был запущен в ответ на вставку в таблицу, с которой связан триггер, и FALSE - в противном случае. UPDATING Возвращает TRUE, если триггер был запущен в ответ на обновление таблицы, с которой связан триггер, и FALSE - в противном случае. DELETING Возвращает TRUE, если триггер был запущен в ответ на удаление из таблицы, с которой связан триггер, и FALSE - в противном случае. Используя эти директивы, можно создаь один общий триггер, который будет объединять действия, необходимые для различных видов операций.

Триггеры DDL Oracle позволяет определить триггеры, которые будут запускаться в ответ на исполнение операторов языка DDL (Data Definition Language - язык определения данных). Оператор DDL - это любой оператор SQL, используемый для создания или изменения объекта базы данных, такого как таблица или индекс. Каждый из этих операторов приводит к созданию, изменению или удалению объекта базы данных. Несколько примеров операторов DDL: CREATE TABLE ALTER INDEX DROP TRIGGER Синтаксис создания таких триггеров практически совпадает с синтаксисом создания триггеров DML, отличие лишь в запускающих их событиях и в том, что триггеры DDL не применяются к отдельным таблицам.

Создание триггера DDL Для создания (или пересоздания) триггера DDL используйте такою конструкцию: 1 2 3 4 5 6 7 8 CREATE [ OR REPLACE ] TRIGGER имя_триггера { BEFORE | AFTER } {DDL событие } ON { DATABASE | SCHEMA } [ WHEN (. . .) } DECLARE Объявления переменных BEGIN. . . код. . . END;

События триггера DDL ALTER Specify ALTER to fire the trigger whenever an ALTER statement modifies a database object in the data dictionary. Restriction on Triggers on ALTER Operations The trigger will not be fired by an ALTER DATABASE statement. ANALYZE Specify ANALYZE to fire the trigger whenever the database collects or deletes statistics or validates the structure of a database object. ANALYZE for information on various ways of collecting statistics ASSOCIATE STATISTICS Specify ASSOCIATE STATISTICS to fire the trigger whenever the database associates a statistics type with a database object. AUDIT Specify AUDIT to fire the trigger whenever the database tracks the occurrence of a SQL statement or tracks operations on a schema object.

События триггера DDL COMMENT Specify COMMENT to fire the trigger whenever a comment on a database object is added to the data dictionary. CREATE Specify CREATE to fire the trigger whenever a CREATE statement adds a new database object to the data dictionary. Restriction on Triggers on CREATE Operations The trigger will not be fired by a CREATE DATABASE or CREATE CONTROLFILE statement. DISASSOCIATE STATISTICS Specify DISASSOCIATE STATISTICS to fire the trigger whenever the database disassociates a statistics type from a database object. DROP Specify DROP to fire the trigger whenever a DROP statement removes a database object from the data dictionary. GRANT Specify GRANT to fire the trigger whenever a user grants system privileges or roles or object privileges to another user or to a role.

События триггера DDL NOAUDIT Specify NOAUDIT to fire the trigger whenever a NOAUDIT statement instructs the database to stop tracking a SQL statement or operations on a schema object. RENAME Specify RENAME to fire the trigger whenever a RENAME statement changes the name of a database object. REVOKE Specify REVOKE to fire the trigger whenever a REVOKE statement removes system privileges or roles or object privileges from a user or role. TRUNCATE Specify TRUNCATE to fire the trigger whenever a TRUNCATE statement removes the rows from a table or cluster and resets its storage characteristics. DDL Specify DDL to fire the trigger whenever any of the preceding DDL statements is issued.

Src="https://present5.com/presentation/52581783_437368378/image-28.jpg" alt="Пример триггера DDL Пример триггера, выполняющего роль информатора, объявляющего о создании всех объектов: SQL>"> Пример триггера DDL Пример триггера, выполняющего роль информатора, объявляющего о создании всех объектов: SQL> CREATE OR REPLACE TRIGGER TRDDL_INF 2 AFTER CREATE ON SCHEMA 3 BEGIN 4 DBMS_OUTPUT. PUT_LINE("I believe you have created something!"); 5 END 6 / TRIGGER created.

Триггеры событий базы данных запускаются при возникновении событий на уровне базы данных. Существует пять триггеров событий базы данных: Событие STARTUP SHUTDOWN Разрешенное время выполнения AFTER BEFORE SERVERERROR AFTER LOGON AFTER LOGOOFF BEFORE Описание Активизируется после запуска экземпляра Активизируется при остановке экземпляра. Для заметки, это событие не активизирует триггер, если останов БД аварийный! Активизируется при возникновении ошибки ORACLE. Активизируется после успешного соединения пользователя с базой данных. Активизируется в начале отключения пользователя.

Создание триггера события базы данных Синтаксис, используемый для создания такого триггера, очень похож на синтаксис создания триггера DDL: 1 2 3 4 5 6 7 CREATE [ OR REPLACE ] TRIGGER имя_триггера { BEFORE | AFTER } { событие_базы_данных } ON { DATABASE | SCHEMA } DECLARE Объявление переменных BEGIN. . . код. . . END;

Триггеры событий базы данных Эти триггеры представляют собой великолепное средство автоматизации процесса администрирования базы данных и обеспечения детального контроля над базой данных. Существует ряд ограничений, накладываемых на использование атрибутов BEFORE и AFTER для определённых событий. Некоторые ситуации представляются просто бессмысленными: Не бывает триггеров BEFORE STARTUP. Попытка создания такого триггера приводит к появлению сообщения об ошибке: ORA 30500: database open triggers and server error triggers cannot have BEFORE type Не бывает триггеров AFTER SHUTDOWN. Попытка создания такого триггера приводит к появлению сообщения об ошибке: ORA 30501: instance shutdown triggers cannot have AFTER type

Триггеры событий базы данных Не бывает триггеров BEFORE LOGON. Попытка создания такого триггера приводит к появлению сообщения об ошибке: ORA 30508: client logon triggers cannot have BEFORE type Не бывает триггеров AFTER LOGOFF. Попытка создания такого триггера приводит к появлению сообщения об ошибке: ORA 30509: client logoff triggers cannot have AFTER type Не бывает триггеров BEFORE SERVERERROR. Попытка создания такого триггера приводит к появлению сообщения об ошибке: ORA 30500: database open triggers and server error triggers cannot have BEFORE type.

Учебное пособие.

Предисловие

Данный документ содержит довольно краткое описание триггеров, используемых в Oracle Forms. Основным материалом для создание методички являлась справочная система к Developer 200 Forms Designer, книга "Oracle Энциклопедия пользователя", а также программы, написанные непосредственно автором данной работы.

Как кажется автору данного документа для выполнения стандартного задания необходимо и возможно достаточно освоить следующие триггеры: WHEN_NEW_INSTANCE_FORM, WHEN_NEW_INSTANCE_ITEM, ON_CHANGE, WHEN_VALIDATE_ITEM, POST_QUERY, ON_ERR.

О событиях и триггерах

Триггеры - это непосредственно куски программного кода, который вы пишите для реализации функциональности вашего приложения. Каждый тригер имеет имя и содержит один или более PL/SQL операторов. Тригер на уровне среды разработки связывается с каким-нибудь событием и выполняется при возникновении этого события.

Имена триггеров соответствуют runtime событиям, с которыми они связаны. Так например тригер "When-Button-Pressed" соответствует событию нажатия кнопки "Button Pressed", в соответсвии с этим, когда пользователь нажимает данную кнопку Oracle Forms .вызывает данный тригер и выполняет его код.

Триггер должен быть связан непосредственно с каким-нибудь объектом, таким как фориа, блок в форме или какой-либо элемент (текстовое поле, кнопка и т.д.) Например в форме с тремя кнопками каждая из них имеет When-Button-Pressed тригер и каждый из этих триггеров содержит различный PL/SQL код. Пользователь нажимает какую-то кнопку и тригер, прикрепленный к этой кнопке (When-Button-Pressed) срабатывает. Очевидно, что остальные тригера When-Button-Pressed, прикрепленные к другим кнопкам не срабатывают.

Типы событий

Oracle Forms обрабатывает определенный набор событий, каждое из которых имеет встроенный триггер (имеется ввиду там нет готового кода, но он может быть написан в этом месте). События можно разделить на группы, об основных из которых будет сказано ниже.

События интрефейса (Interface Events)

События данной группы очевидны (связаны с элементами интерфейса):

Событие - Имя триггера

  • Pressing a button(нажатие кнопки) -When-Button-Pressed
  • Clicking a check box (нажатие check-boxa)-When-CheckBox-Changed
  • Pressing the Tab key (нажатие Tab-Key) Key-NxtItem

События внутреннего выполнения (Internal Processing Events)

Рассмотрим форму с двумя блоками A и B, в каждом из которых есть по текстовому полю. Для GUI платформ, пользователь может переместить фокус ввода с элемента из Блока A в элемент Блока В нажав мышкой на последний. Хотя эта операция включает только одно действие (нажатие мышки на элементе блока В) на самом деле она вызывает целый ряд событий, каждое из которых может иметь собственный триггер Рассмотрим эту последовательность событий и связанные с ними триггеры.

  • Событие - Имя триггера
  • Validate the item (Проверяется элемент на корректность введенных данных)
  • When-Validate-Item (соответствует или нет определенным условиям)
  • Leave the item ("покидаем") элемент (убираем фокус ввода)-Post-Text-Item
  • Validate the record (проверяем запись)-When-Validate-Record
  • Leave the record ("покидаем запись")-Post-Record
  • Leave the block ("покидаем блок") Post-Block
  • Enter the block ("делаем активным блок")- Pre-Block
  • Enter the record ("делаем активной запись")-Pre-Record
  • Enter the Item (устанавливаем фокус ввода на элементе) Pre-Text-Item
  • Ready block for input (блок готов для ввода)- When-New-Block-Instance
  • Ready record for input (запись готова для ввода)When-New-Record-Instance
  • Ready item for input (элемент готов для ввода) When-New-Item-Instance

Важно понимать, что навигационные события, такие как "Leave the Item" и "Enter the Block" возникают в ходе внутренней навигации в форме, что соотвествует переходам между объектами иерархии в.Oracle Forms.

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

Модель, используемая Oracle Forms, гарантирует целостность данных в рамках элемента, записи, блока и формы. Для каждого из перечисленных объектов в данной модели имеется свой уровень. Как будет показанно дальше для каждого уровня определен набор тригеров, позволяющих реализовать требуемю функциональность приложения

Обзор категорий триггеров

Этот параграф содержит обзор наиболее часто используемых триггеров, сгруппированных по функциональным категориям

  • "тригеры блоков" (block-processing triggers)
  • "интерфейсные" тригеры (interface event triggers)
  • тригеры, связанные с использованием связанных блоков (мастер-деталь, один- ко многим) (master-detail triggers)
  • тригеры управления сообщениями (message-handling triggers)
  • "навигационные" тригеры (тригеры перехода)(navigational triggers)
  • "тригеры запросов" (query-time triggers)
  • "тригеры транзакций" (transactional triggers)
  • "тригеры проверок" (validation triggers)

Триггеры блоков (Block Processing Triggers )

Тригеры блоков срабатывают при возникновении событий, связанных с управлением записями в блоках.

When-Create-Record ("Когда создается новая запись")

Срабатывает при попытке Oracle Forms создать новую запись в блоке. Может быть использованно для задания значения по умолчанию в сложных ситуациях, напрмер когда оно(значение по умолчанию) может зависеть от уже введенных данных (напрмер в предыдущей записи). Разумеется в простых случаях пользуйтесь свойством DefaultValue для элементов.

When-Clear-Block

Срабатывает, когда Oracle Forms удаляет все записи из текущего блока

When-Database-Record

Срабатывает, когда Oracle Forms изменяет статус записи на Insert (для новой записи) or Update (для измененной уже хранящейся). Этот статус указывает, что данная запись будет обработана следующей COMMIT_FORM операцией (т.е. будет обработана сервером) .

When-Remove-Record

Срабатывает, когда какая-нибудь запись удаляется. Может быть использовано для пересчета "итоговых сум" по блоку

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

Под этим блоком расположен другой блок BLOCK_ITOGI. В нем имеются поля - сумма по зарплате и премии для всех введенных сотрудников. Чтобы пересчитаь сумму по зарплате при удалении одной из записи достаточно ввести текст:

Begin:BLOCK_ITOGI.TOT_ZARPLATA:=:BLOCK_ITOGI.TOT_ZARPLATA-:T_LUDI.ZARPLATA; end;

"Интерфейсные" Триггеры (Interface Event Triggers)

"Интерфейсные" триггеры срабатывают (что следует из их названия) при возникновении событий интерфейса. Некоторые из них (такие как When-Button-Pressed), срабатывают только при непосредственных действиях пользователя. Другие, как When-Window-Activated, могут быть сработать в результате как непосредственно действия пользователя (мышку поставил на этот экран) так и в результате действий программы (открыл форму командой OPEN_FORM).

Приведем основные тригеры данной категории и их возможное использование

When-Button-Pressed

Наиболее часто используемый тригер, срабатывает когда пользователь нажимает кнопку

Пример 2 Для вычисления общих сумм по зарплате и премии с поиощью кнопки "ВЫЧИСЛИТЬ"

Begin do_key("commit_form"); select sum(T_LUDI.ZARPLATA) into:BLOCK_ITOGI.TOT_ZARPLATA from T_LUDI; select sum(T_LUDI.PREMIA) into:BLOCK_ITOGI.TOT_PREMIApremia from T_LUDI; end;

When-CheckBox-Changed

Срабатывает, когда пользователь переключает состояние check-box-a

When-Image-Activated

Срабатывает, когда пользователь дважды нажимает на картинку (image item)

When-Image-Pressed

Срабатывает, когда пользователь нажимает на картинку (image item)

Key-

Заменяет действия связанные с данными "функциональными" клавишами. Например вы можете написать тригер Key-EXIT , чтобы заменить стандартный выход.

When-Radio-Changed

Срабатывает, когда пользователь изменяет текущую "выбранную" кнопку в радио-группе.

When-Timer-Expired

Срабатывает, когда время программного таймеа истекает Используйте тригер When-Timer-Expired для обновления значений каких-либо элементов или выполнения любых других заданий, которые должны случиться через определенный промежуток времени

When-Window-Activated

Срабатывает, когда пользователь или приложение активизирует окно. Может быть использован для получения в программе начальных значений свойств окна с помощью встроенной функции GET_WINDOW_PROPERTY, а также для автоматической установки фокуса на определенный элемент взависимости от ситуации.

When-Window-Closed

Срабатывает, когда пользователь закрывает окно с помощью Close команды.

When-Window-Deactivated

Срабатывает, когда окно становится неактивным например в результате активизации другого окна

When-Window-Resized

Срабатывает, когда окно изменяется в размерах пользователем или программно (например с помощью RESIZE_WINDOW or SET_WINDOW_PROPERTY.)

Мастер-деталь

Триггеры (Master-Detail Triggers) Oracle Forms генерирует мастер-деталь триггеры автоматически, когда вы определяете связь между блоками. Сгенерированные тригеры обеспечивают координацию между записямт в главном(мастер) блоке и в подчиненном (деталь) блоке. Это выражается например, что при переходе на запись в главном блоке, автоматически в подчиненном появляются записи, связанные с выбранной в главном. Если вы не хотите создать свою специальную систему связи, то вам нет необходимости, что-нибудь менять в сгенерированном коде.

Приведем основные тригеры данной категории и их возможное использование

On-Check-Delete-Master

Срабатывает, когда Oracle Forms пытается стереть в главном(мастер) блоке

On-Clear-Details

Срабатывает, когда Oracle Forms требуется удалить записи из подчиненного блока так как в главном связанной записи больше нет (после удаления ее оттуда)

On-Populate-Details Fires

Срабатывает, когда Oracle Forms требуется синхронизировать содержимое подчиненного блока с активной записью в главном блоке

Тригеры управления сообщениями (Message-Handling Triggers)

Oracle Forms автоматически использует соответсвующие информационные или об ошибках сообщения при возникновении соответствующих событий. Тригеры данной категории срабатывают в ответ на эти события

On-Error

Срабатывает, когда Oracle Forms "собирается" выдать сообщение об ошибке.Данный тригер рекомендуется использовать для

  • обработки возникающих ошибочных ситуаций
  • для замены стандартных сообщений - своими сообщениями

Пользуйтесь ERROR_CODE, ERROR_TEXT, ERROR_TYPE, DBMS_ERROR_TEXT, или DBMS_ERROR_CODE встроенными функциями для уточнения условий приведших к "ошибке" (к исключению)

В большинстве случаев On-Error тригера следует "привязать" к форме, а не к блоку или элементу. Так как "отлов" определенных ошибок может быть затруднен, когда Oracle Forms выполняет внутреннюю навигацию, такую как во время Commit процесса

Считая этот тригер очень важным, приведем пример из HELP System

В данном примере проверяется код ошибки и в случае определенных значений указаны ветки кода их обработки

DECLARE lv_errcod NUMBER:= ERROR_CODE; lv_errtyp VARCHAR2(3) := ERROR_TYPE; lv_errtxt VARCHAR2(80) := ERROR_TEXT; BEGIN IF (lv_errcod = 40nnn) THEN /* ** Выполнение некоторых действий по обработке */ ELSIF (lv_errcod = 40mmm) THEN /* **Выполнение некоторых действий по обработке */ ... ... ELSIF (lv_errcod = 40zzz) THEN /* **Выполнение некоторых действий по обработке */ ELSE Message(lv_errtyp||"-"||to_char(lv_errcod)||": "||lv_errtxt); RAISE Form_Trigger_Failure; END IF; END;

On-Message

Ловит сообщения. Может быть использовано для замены стандартного своим. Чтобы определить данное сообщение об ошибке или информационное пользуйтесь Oracle Forms Codes (MESSAGE_CODE, MESSAGE_TEXT, MESSAGE_TYPE, DBMS_MESSAGE_CODE, or DBMS_MESSAGE_TEXT).

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

DECLARE alert_button NUMBER; lv_errtype VARCHAR2(3) := MESSAGE_TYPE; lv_errcod NUMBER:= MESSAGE_CODE; lv_errtxt VARCHAR2(80) := MESSAGE_TEXT; BEGIN IF lv_errcod = 40350 THEN alert_button:= Show_Alert("continue_alert"); IF alert_button = ALERT_BUTTON1 THEN ... ELSE ... END IF; ELSE Message(lv_errtyp||"-"||to_char(lv_errcod)||": "||lv_errtxt); RAISE Form_Trigger_Failure; END IF; END;

"Навигационные" триггеры (Navigational Triggers)

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

Навигационные события возникают на различных уровнях иерархии объектов Oracle Forms (формы, блоки, записи, элементы). Навигационные тригеры можно разделить по следующим категориям: До- (Pre-), После-(Post-) и Когда-Новый-Экземпляр (When-New-Instance) тригеры.

Pre- and Post- триггеры

Pre- и Post- тригеры срабатывают, когда Oracle Forms осуществляет внутренние переходы между различными уровнями объектной иерархии Эти тригеры отрабатываются в ответ на действия пользователя, такие как нажатие кнопки (Следующий элемент), а также при внутренних переходах, когда Oracle Forms выполняет некоторые стандартные действия.

Приведем основные тригеры данной категории и их возможное использование

Pre-Form

Выполняется перед тем, как Oracle Forms "переходит" от внешней формы к данной. Может быть использован для:

  • назначения уникального значения ключу из последовательности (В общем случае это рекомендуется делать с помощью табличного тригера Before-Insert)
  • ограничения доступа к форме
  • инициализации глобальных переменных

Pre-Block

срабатывает перед тем, как Oracle Forms переходит с уровня формы на уровень блока. Возможное его использование:

  • позволить или не позволить доступ к блоку
  • установить значение переменных

Pre-Text-Item

срабатывает перед тем, как Oracle Forms переходит с уровня записи на уровень элемента (а также при переходе от одного элемента к другому в рамках той же записи). Возможное его использование:

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

Post-Text-Item

Срабатывает перед тем как Оracle Forms снимет фокус ввода с этого элемента. Можно использовать этот тригер для вычисления или изменения значений элемента. Помимо этого удобно использовать этот тригер для изменения визуальных атрибутов элемента (таких как фон и цвет текста).

Пример

Чтобы при нахождении курсора на поле это поле было выделено можнго использовать пару тригеров (When-New-Item-Instance,Post-Text-Item ) для изменения свойства визуальных атрибутов. Соответственно, первый из них устанавливает VISUAL_ATRIBUTE например в VISUAL_WHITE_ON_RED, а второй возвращает в обычное состояние.

BEGIN SET_ITEM_PROPERTY("T_LUDI.FAMILIA",VISUAL_ATTRIBUTE,"VISUAL_USSUAL"); END;

Post-Record

Срабатывает, когда Oracle Forms "оставляет" запись. Это происходит когда фокус ввода уходит с данной записи например к другой записи. При переходе к элементу вне данного блока управление переходит к тригерам уровня блока. Может быть использован для установки свойства visual attribute для активной записи, также как это было описано выше для одного элемента

Post-Block

Срабатывает, когда Oracle Forms "оставляет" блок и переходит на уровень формы.Может быть использован для

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

Post-Form

Срабатывает перед тем, как Oracle Forms переходит к другой форме.

When-New-Instance-Триггеры

When-New-Instance тнриггеры срабатывают после последовательности переходов по иерархии объектов Oracle Forms, результатом которой, является перемещение фокуса ввода к данному элементу. На самом деле этот тригер выполняется, когда фокус уже установлен и форма готова к вводу пользователя. В отличии от триггеров Pre- и Post- тригеры When-New-Instance не срабатывают при внутренних навигационных событиях.

Приведем основные тригеры данной категории и их возможное использование

When-New-Form-Instance

Выполняется при запуске формы, после выполнения всех навигационных переходов. Может быть использован для загрузки данных в форму, а также для установки глобальных переменных.

Пример

Данный пример из HELP System, был использован автором много раз. В нем форма заполняется данными из соответствующих таблиц. При автоматическом построении формы с помощью Forms Designer этот триггер не создается, но можно выбрать при создании панель кнопок, одна из которых "Query" выполняет тоже самое, однако из-за специфики реализации ее приходится нажимать два раза.

BEGIN Setup_My_Global_Variables; --переходим к главному блоку (в отношении мастер-деталь) Go_Block("Glavnii_Block"); /* ** Подавляем стандартные "рабочие" сообщения */ :System.Suppress_Working:= "TRUE"; --непосредственно выполняем запрос Execute_Query; :System.Suppress_Working:= "FALSE"; END;

When-New-Block-Instance

Срабатывает сразу после того, как фокус ввода переходит от элемента из одного блока к элементу из другого. Это происходит уже тогда, когда Oracle Forms готов принимать вводимые пользователем данные, тоесть уже после "последовательности навигационных событий."

When-New-Record-Instance

Выполняется после перехода фокуса от элемента из одной записи к элементу в другой записив Это происходит уже тогда, когда Oracle Forms готов принимать вводимые пользователем данные, тоесть уже после "последовательности навигационных событий. Если новая запись находится в другом блоке по отношению к предыдущей, тогда данный триггер вызывается после When-New-Block-Instance, но перед When-New-Item-Instance триггером.

When-New-Item-Instance

Выполняется после перехода фокуса к данному элементу. Это происходит, когда Oracle Forms готов принимать вводимые пользователем данные, то есть уже после "последовательности навигационных событий Как было сказано выше этот тригер можно использовать для изменения визуальных атрибутов элемента при получении им фокуса ввода.

Query-Time Триггеры

Триггеры запросов (query-time triggers) срабатывают непосредственно ДО или ПОСЛЕ того, как оператор или приложение запускает запрос в блоке.

Типичное использование триггеров запросов:

  • Pre-Query - Обрабатывает условия запроса или добавляет дополнительные условия непосредственно перед посылкой управляющего слова SELECT в БД.
  • Post-Query - Исполняется после получения выборки, например, для поиска значений в других таблицах на основе полученной в выборке информации. Запускается один раз для каждой записи из выборки.

Transactional Триггеры

Триггеры транзакций (transactional triggers) срабатывают на широком диапазоне событий, возникающих при взаимодействии форм и таблиц БД.

Основные тригеры данное категории:

  • On-Delete - Заменяет стандартный процесс управления удаляемыми записями в Oracle Forms.
  • On-Insert - Заменяет стандартный процесс управления вставляемыми записями в Oracle Forms.
  • On-Lock - Замена стандартной блокировки записей таблицах БД.
  • On-Logon - Замена стандартных операций Oracle Forms для соединения с ORACLE. Применяется в основном для обработки событий, когда форме не требуется получать соединение с ORACLE, например, при взаимодействии с таблицами иными, нежели ORACLE.
  • On-Logout - Замена стандартного процесса Oracle Forms при отключении от ORACLE.
  • On-Update - Замена стандартного процесса Oracle Forms , отвечающего за обновления записей в таблицах.
  • Post-Database-Commit - Добавление дополнительных функций в Oracle Forms при завершении операции с БД.
  • Post-Delete - Проверочные транзакции при удалении записи из БД.
  • Post-Forms-Commit - Добавление доп. Функций в стандартную процедуру завершения обмена в формой перед окончанием транзакции.
  • Post-Insert - Проверочные транзакции при вставка записи в БД.
  • Post-Update - Проверочные транзакции при убновлении записи БД.
  • Pre-Commit - Производит срочные операции до выполнения транзакций Post и Commit.
  • Pre-Delete - Управление записью перед ее удалением из БД стандартными транзакциями Post и Commit; например, для защиты записей, удовлетворяющих определенным условиям, от удаления.
  • Pre-Insert - Управление записью перед тем, как она будет вставлена в БД с помощью стандартных транзакций Post и Commit.
  • Pre-Update - Управление записью перед тем, как будут внесены изменения в запись с помощью стандартных транзакций Post и Commit.