- •Структурированный язык запросов sql. Оператор delete. Структура оператора и примеры использования. Примеры использования delete с вложенными подзапросами.
- •Структурированный язык запросов sql. Оператор insert. Структура оператора и примеры использования. Использование insert с вложенными подзапросами.
- •Структурированный язык запросов sql. Оператор update. Структура оператора и примеры использования. Использование update с вложенными подзапросами.
- •Выборка данных оператором select. Структура оператора и примеры использования. Способы задания отображаемых полей. Использование distinct. Выборка значений с упорядочиванием.
- •Использование фразы where в операторах sql. Способы задания логических выражений в sql. Операторы in, like, between. Использование значения null в логических выражениях.
- •7 Вложенные подзапросы. Типы вложенных подзапросов. Способы включения вложенных подзапросов. Примеры использования вложенных подзапросов с разными способами включения.
- •Создание таблиц
- •Пример создания таблиц
- •Модификация таблиц
- •Удаление таблиц
- •Создание представлений. Правила создания модифицируемых представлений. Достоинства и недостатки представлений. Особенности определения полей представлений. Примеры использования.
- •Хранимые процедуры InterBase. Виды хранимых процедур. Расширения языка sql для использования в хранимых процедурах. Примеры создания хранимых процедур и их вызова.
- •Расширения языка sql для использования в хранимых процедурах и триггерах. Циклы и ветвления. Обработка исключений и ошибок.
- •Генераторы InterBase. Создание генераторов. Установка значений генераторов. Получение значений генераторов из
- •Триггеры InterBase. Типы триггеров. Контекстные переменные. Примеры создания триггеров для автоинкрементных полей и протоколирования изменений.
- •17. Транзакции в InterBase. Механизм транзакций. Параметры транзакций. Уровни изоляции и способы их задания в InterBase. Управление транзакциями. Примеры использования.
- •18. Библиотека доступа InterBase eXpress. Основные компоненты. Подключение к базе данных InterBase и организация просмотра и модификации данных.
- •20.Особенности системы защиты данных в InterBase. Пользователи и роли: создание и удаление. Вида прав. Раздача
Расширения языка sql для использования в хранимых процедурах и триггерах. Циклы и ветвления. Обработка исключений и ошибок.
Циклы и операторы ветвления
Помимо команды FOR SELECT... DO, организующей цикл по записям какой-либо выборки, существует другой вид цикла - WHILE...DO, который позволяет организовать цикл на основе проверки любых условий. Вот пример ХП, использующей цикл WHILE.. DO. Эта процедура возвращает квадраты целых чисел от 0 до 99: CREATE PROCEDJRE QUAD RETURNS (QUADRAT INTEGER) AS DECLARE VARIABLE I INTEGER; BEGIN I = 1; WHILE (i<100) DO BEGIN QUADRAT= I*I; I=I+1; SUSPEND; END END В результате выполнения запроса SELECT • FROM QUAD мы получим таблицу, содержащую один столбец QUADRAT, в котором будут квадраты целых чисел от 1 до 99 Помимо перебора результатов SQL-выборки и классического цикла, в языке хранимых процедур используется оператор IF...THEN..ELSE, позволяющий организовать ветвление в зависимости от выполнения каких-либо условий
Вычисляет среднюю цену в таблице Table_example (см. глава "Таблицы Первичные ключи и генераторы")
Далее для каждой записи в таблице делает след>ющ)ю проверку, если существующая цена (PRICE) больше средней цены, то устанавливает цену, равную величине средней цены, плюс задаваемый фиксированный процент
Если существующая цена меньше или равна средней цене, то устанавливает цену, равную прежней цене, плюс половина разницы между прежней и средней ценой.
Возвращает все измененные строки в таблице.
CREATE PROCEDURE IncreasePrices ( Percent2Increase DOUBLE PRECISION) RETURNS (ID INTEGER, NAME VARCHAR(80), new_price DOUBLE PRECISION) AS DECLARE VARIABLE avg_price DOUBLE PRECISION; BEGIN SELECT AVG(Price_l) FROM Table_Example INTO :avg_price; FOR SELECT ID, NAME, PRICE_1 FROM Table_Example INTO :ID, :NAME, :new_price DO BEGIN /*здесь обрабатываем каждую запись*/ IF (new_pnce > avg_price) THEN /*если существующая цена больше средней цены*/ BEGIN /*установим новую цену, равную величине средней цены, плюс фиксированный процент */ new_price = (avg_price + avg_price*(Percent2lncrease/100)); UPDATE Table_example SET PRICE_1 = :new_price WHERE ID = :ID; END ELSE BEGIN /* Если существующая цена меньше или равна средней цене, то устанавливает цену, равную прежней цене, плюс половина разницы между прежней и средней ценой */ new_price = (new_price + ((avg_price - new_price)/2)); UPDATE Table_example SET PRICE_1 = :new_price WHERE ID = :ID; END SUSPEND; END END Данный пример хранимой процедуры иллюстрирует применение основных конструкций языка хранимых процедур и триггеров. Далее мы рассмотрим способы применения хранимых процедур для решения некоторых часто возникающих задач.
Расширенные возможности языка хранимых процедур InterBase
Обработка исключений и ошибок
Исключения
Создается исключение следующим образом: СРЕАТЕ EXCEPTION <имя_исключения> <текст_исключения>; Например, мы можем создать исключение такого вида: CREATE EXCEPTION test_except 'Test exception'; Исключение легко удалить или изменить - удаление совершается командой DROP EXCEPTION <имя_удаляемого_исключения>, а изменение - ALTER EXCEPTION <имя_исключения> <текст_исключения> Чтобы использовать исключение в хранимой процедуре или триггере, необходимо воспользоваться командой следующего вида: EXCEPTION <имя_исключения>; Нам необходимо отследить случай деления на нуль и возбудить исключение, если делитель равен нулю. Для нашего примера создадим следующее исключение: CREATE EXCEPTION zero_divide 'Cannot divide by zero!'; Создадим хранимую процедуру, использующую это исключение: CREATE PROCEDURE sp_test_except(Delltel DOUBLE PRECISION) RETURNS (rslt DOUBLE PRECISION, status VARCHAR(SO)) AS BEGIN Status='Everything is Ok'; SELECT result FROM sp_divide(12,:Delitel) INTO :rslt; SUSPEND; WHEN EXCEPTION Zero_divide DO BEGIN Status='zero value found!'; rslt=-l; SUSPEND; END END Эта процедура вызывает процедуру SP_DIVIDE. Если параметр Delitel не равен нулю, то процедура SP_DIVIDE выполняется без проблем и в возвращаемое значение rslt помещается частное от деления, а статусная переменная status принимает значение 'Everything is Ok'. В случае, если возникла исключительная ситуация деления на нуль, то результирующая переменная rslt будет равна -1, а в переменной status будет содержаться сообщение об ошибке - 'zero value found!'. Разумеется, в обработчике исключения можно произвести и более сложную обработку, например записать некорректные данные в особую таблицу или попытаться изменить данные для выполнения операции и вновь попробовать ее выполнить и т. д.
Обработка ошибок SQL и InterBase
Ошибка - это фактически то же самое исключение, только возбуждаемое InterBase. Принцип обработки ошибок тот же самый что и исключений: если возникает какая-то ошибка, то сервер ищет ее обработчик, последовательно просматривая все уровни вложенности (если они есть) хранимой процедуры, начиная с того уровня, на котором возникла ошибка. Если обработчик найден, то выполняется код внутри его, а затем управление передается на первый оператор за обработчиком исключений. Конструкция, с помощью которой производится обработка ошибок, такая же, как и для обработки исключений, только вместо EXCEPTION стоит либо GDSCODE, либо SQLCODE: WHEN GDSCODE SQLCODE <код_ошибки> DO BEGIN /*обрабатываем ошибку*/ END В зависимости от того, стоит ли в конструкции обработки ошибок GDSCODE или SQLCODE, обрабатываются различные ошибки. Если стоит SQLCODE, то обрабатываются ошибки SQL, а если GDSCODE - то ошибки InterBase. Примером ошибки SQL является ошибка с SQLCODE=-802 "Arithmetic exception, numeric overflow, or string truncation" или SQLCODE=-817 "Attempted update during read-only transaction" Список ошибок SQL и соответствующих им значений SQLCODE приведен в таблице "SQLCODE codes and messages'. Примером ошибки InterBase является ошибка isc_bad_dbkey 335544322L "invalid database key". Таким образом, внутри хранимой процедуры можно "перехватить" практически любую ошибку и корректно на нее отреагировать. Можно перечислять обработчики ошибок один за другим, чтобы определить реакцию на разные ошибки. Для того чтобы написать безусловный обработчик, реагирующий на любую ошибку - SQL, InterBase или исключение, следует воспользоваться конструкцией WHEN DO с ключевым словом ANY: WHEN ANY DO BEGIN /*действия при любой нестандартной операции ошибке или исключении */ END