Разработка серверного кода
При возникновении исключительной ситуации в системе происходит автоматическая передача управления в блок EXCEPTION программы PL/SQL.
Рассмотрим пример обработки исключительной ситуации в программе, когда кодировщик пропустил оператор открытия курсора.
Пример
DECLARE
X1 T01_A1%TYPE;
X2 T01_A2%TYPE;
X3 T01_A3%TYPE;
CURSOR CUR1 IS SELECT * FRON T01;
BEGIN
WHILE CUR1%FOUND LOOP
FETCH CUR1 INTO X1,X2,X3;
DBMS_OUTPUT.PUT_LINE (X1||' '||X2||' '||X3);
END LOOP
EXCEPTION
WHEN INVALID_CURSOR THEN
DBMS_OUTPUT.PUT_LINE ('ОШИБКА. НЕ ОТКРЫТ КУРСОР1');
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE ('НЕИЗВЕСТНАЯ ОШИБКА.');
END;
/Для обработки ситуаций, не входящих в перечень стандартных, можно использовать специальный обработчик PL/SQL OTHERS или описать пользовательскую исключительную ситуацию и запрограммировать ее обработку. Ключевое слово OTHERS блока EXCEPTION определяет универсальный алгоритм обработки исключительных ситуаций, не входящий в список стандартных.
Исключительная ситуация, задаваемая пользователем, должна быть описана в блоке DECLARE, как Имя исключительной ситуации EXCEPTION. После обнаружения исключительной ситуации в программе PL/SQL она должна быть сгенерирована указанием ключевого слова и имени исключительной ситуации - RAISE Имя исключительной ситуации. В блоке EXCEPTION должен быть предусмотрен код для ее обработки.
Например,
DECLARE … User_ecx EXCEPTION; … BEGIN IF x1 < 0 THEN RAISE User_exc; END IF; … EXCEPTION WHEN User_exc THEN DBMS_OUTPUT.PUT_LINE (ПОЛЬЗОВАТЕЛЬСКАЯ ИСКЛЮЧИТЕЛЬНАЯ СИТУАЦИЯ.'); …
В этом разделе мы рассмотрели основные конструкции расширения SQL в Oracle PL/SQL. Для более глубокого изучения этого языка следует обратиться к списку литературы или документации.
Создание хранимых процедур и функций
Определение хранимых процедур и функций в PL/SQL
Процедура или функция PL/SQL имеет уникальное имя. Как и программы на PL/SQL, процедуры и функции имеют блок объявлений, блок исполняемого кода и, опционально, блок обработки исключительных ситуаций. Но процедура может принимать и возвращать значения параметром, а функция дополнительно возвращает значение.
Описание процедуры имеет следующий синтаксис:
PROCEDURE имя [(параметр [, параметр, ...])] IS [объявление локальных переменных, пользовательских типов данных, пользовательских исключительных ситуаций, локальных подпрограмм и функций] BEGIN Исполняемый код [EXCEPTION обработчики исключительных ситуаций] END [имя];
Параметры процедуры обеспечивают входные и выходные данные процедуры. Параметров у процедуры может и не быть, так что этот раздел не является обязательным. Для задания параметров используется следующий синтаксис:
Имя параметра [IN | OUT | IN OUT] тип данных [{:= | DEFAULT} выражение]В определении параметров нельзя использовать ограничение NOT NULL, а в определении типа данных нельзя использовать никакие ограничения. Для каждого параметра должен быть указан его тип (parameter mode) - IN, OUT или IN OUT. Указание типа IN означает, что значение параметра определяется при обращении к процедуре и не изменяется процедурой. Попытка изменить такой параметр в теле процедуры приведет к возникновению ошибки. Указание типа OUT предполагает изменение значения параметра в процессе выполнения процедуры, т.е. это возвращаемый параметр. Указание типа IN OUT говорит о том, что при вызове процедуры такому параметру должно быть присвоено значение, которое может быть изменено в теле процедуры. Типом по умолчанию считается IN. Ниже в таблице 12.2 суммирована информация о типах параметров.
| IN | OUT | IN OUT |
|---|---|---|
| Умолчание | Должен быть задан | Должен быть задан |
| Передает значение в процедуру или функцию | Возвращает значение из процедуры или функции | Передает значение в процедуру или функцию и возвращает измененное значение |
| Формальный параметр действует как константа | Формальный параметр действует как неинициализированная переменная | Формальный параметр действует как неинициализированная переменная |
| Формальному параметру не может быть присвоено значение | Формальный параметр не может быть использован в выражении, и ему должно быть присвоено значение | Формальному параметру можно присваивать значение |
| Действительный параметр может быть константой, инициализированной переменной, литеролом или выражением | Действительный параметр должен быть переменной | Действительный параметр должен быть переменной |
Определение процедуры начинается с ключевого слова PROCEDURE и заканчивается именем процедуры или списком параметров. Тело процедуры начинается с ключевого слова IS и заканчивается ключевым словом END. Тело процедуры состоит из трех частей, которые отвечают блокам программы PL/SQL.
Пример. Для нашей учебной базы данных можно рассмотреть вопрос о создании процедуры, которая увеличивает зарплату сотрудника по значению его номера.
PROCEDURE raise_salary (empid INTEGER, increase REAL) IS
current_salary REAL;
salary_missing EXCEPTION;
BEGIN
SELECT sal INTO current_salary FROM employee WHERE
empno = emp_id;
IF current_salary IS NULL THEN
RAISE salary_missing;
ELSE
UPDATE employee SET sal = sal + increase
WHERE empno = emp_id;
END IF;
EXCEPTION
WHEN NO_DATA_FOUND THEN
INSERT INTO emp_audit VALUES (emp_id, 'Нет сотрудника
с таким номером');
WHEN salary_missing THEN
INSERT INTO emp_audit VALUES (emp_id, Зарплата не назначена');
END raise_salary;При вызове процедура принимает номер сотрудника и величину прибавки к зарплате в качестве параметров. Номер сотрудника используется далее для выборки значения текущей зарплаты из таблицы EMPLOYEE в локальную переменную current_salary. Если номер сотрудника не найден в базе данных или значение зарплаты не установлено, то возникают исключительные ситуации, стандартная и определенная пользователем соответственно. В противном случае зарплата обновляется.
Процедура вызывается как команда PL/SQL
raise_salary (emp_num, amount);
В примере использована вспомогательная таблица базы данных emp_audit для отслеживания возникновения ошибочных ситуаций при работе с базой данных.
Рассмотрим еще один пример использования процедуры для выборки зарплаты служащего по его фамилии из таблицы EMPLOYEE учебной базы данных.
PROCEDURE emp_salary (sName INTEGER, sal_p OUT REAL) IS
current_salary REAL;
salary_missing EXCEPTION;
BEGIN
SELECT sal INTO current_salary FROM employee WHERE ENAME=:sName';
IF current_salary IS NULL THEN
RAISE salary_missing;
ELSE
sal_p = current_salary
END IF;
EXCEPTION
WHEN NO_DATA_FOUND THEN
INSERT INTO emp_audit VALUES (emp_id, 'Нет сотрудника
с такой фамилией');
WHEN salary_missing THEN
INSERT INTO emp_audit VALUES (emp_id, Зарплата не назначена');
END raise_salary;Описание функции имеет следующий синтаксис:
FUNCTION имя [(параметр [, параметр, ...])] RETURN тип данных IS [объявление локальных переменных, пользовательских типов данных, пользовательских исключительных ситуаций, локальных подпрограмм и функций] BEGIN Исполняемый код [EXCEPTION обработчики исключительных ситуаций] END [имя];
Как можно видеть, описание функции отличается от описания процедуры наличием в спецификации процедуры предложения RETURN с указанием типа возвращаемого значения. Возврат значения функции выполняется командой PL/SQL RETURN.
Пример. Рассмотрим пример функции, которая возвращает логическое значение "истина" или "ложь", если зарплата служащего находится в установленных пределах.
FUNCTION sal_ok (salary REAL, title REAL) RETURN BOOLEAN IS
min_sal REAL;
max_sal REAL;
BEGIN
SELECT losal, hisal INTO min_sal, max_sal
FROM salaryes WHERE job = title;
RETURN (salary >= min_sal) AND (salary <= max_sal);
END sal_ok;При вызове функции она принимает зарплату сотрудника и его должность в качестве входных параметров. Она выбирает установленные нижнюю и верхнюю границы зарплаты из таблицы базы данных salaryes для заданной должности. В предложении RETURN идентификатор функции sal_ok устанавливается к логическому значению в результате проверки.
Функция вызывается как часть выражения PL/SQL, где идентификатор функции действует как переменная, значение которой зависит от параметров, например
IF sal_ok(new_sal, new_title) THEN ...