Информационное обеспечение



бет16/56
Дата05.03.2023
өлшемі256,49 Kb.
#71567
түріПрактикум
1   ...   12   13   14   15   16   17   18   19   ...   56
Функции. Функции – это подпрограммы, которые подсчитывают и воз- вращают какое-либо значение. Возвращаемое функцией значение принадлежит к определенному типу данных. В отличие от процедур вызов функции всегда является частью оператора, т. е. включается в выражение либо служит в каче- стве значения по умолчанию. Функции, определенные пользователем, могут использоваться в SQL-выражениях.
Функции играют важную роль в обеспечении модульного подхода про- граммирования. К примеру, реализация отдельного бизнес-правила или форму- лы должна помещаться в функцию. Любой запрос, возвращающий одну строку, может также объявляться внутри функции для его повторного использования.
[CREATE [OR REPLACE ] ]
FUNCTION имя_функции[ (параметр1 [ , параметр2 ]... ) ]
RETURN тип_возвращаемого_результата
[ AUTHID { DEFINER | CURRENT_USER } ] [ PARALLEL_ENABLE ]
[DETERMINISTIC] [ PIPELINED ]
{IS | AS}
[ PRAGMA AUTONOMOUS_TRANSACTION; ]
[ локальные объявления переменных] BEGIN
Исполняемые_операторы [ EXCEPTION
обработка_ошибок] END [ имя_функции];
где PARALLEL_ENABLE – атрибут, используемый для оптимизации, позволя- ет системе выполнять функцию параллельно в случае, когда она вызывается из оператора SELECT;
DETERMINISTIC – атрибут, используемый для оптимизации, позволяет системе применить сохраненную копию возвращаемого функцией значения, ес- ли это возможно;
PIPELINED – атрибут, указывающий, что результат табличной функции должен возвращаться построчно, с помощью оператора PIPE ROW.
тип_возвращаемого_результата – функция, которая может возвращать лю- бые данные, определенные в Oracle.
Функция, которая возвращает количество отработанных сотрудником лет и месяцев для схемы HR:

CREATE OR REPLACE FUNCTION get_time_work ( empid employees.employee_id%TYPE,


dateval DATE DEFAULT SYSDATE
)
RETURN VARCHAR2 IS
RESULT INTERVAL YEAR TO MONTH;
d employees.hire_date%TYPE; BEGIN
SELECT hire_date INTO d FROM employees WHERE employee_id = empid;
RESULT:= (dateval - d) YEAR TO MONTH; RETURN RESULT;
END;
/

Параметр dateval описан ключевым словом DEFAULT, что позволяет при обращении к функции не задавать его значение, если значение по умолчанию устраивает.


Вызов функции может осуществляться в любом месте исполняемого опе- ратора, где возможно использование выражения, следовательно, вызвать функ- цию можно следующими способами:

  • в команде присваивания:

DECLARE
time INTERVAL YEAR TO MONTH; BEGIN


time := get_time_work (108); DBMS_OUTPUT.PUT_LINE(time); END;

  • при задании значения по умолчанию:

DECLARE
time INTERVAL YEAR TO MONTH DEFAULT get_time_work (108); BEGIN


DBMS_OUTPUT.PUT_LINE(time); END;

  • в логическом выражении:

DECLARE
time INTERVAL YEAR TO MONTH; BEGIN
IF get_time_work (107) < INTERVAL '10-00' YEAR TO MONTH THEN
time := get_time_work (107); DBMS_OUTPUT.PUT_LINE(time); END IF;
END;

  • в команде SQL:

SELECT employee_id, first_name, get_time_work (employee_id) FROM employees


WHERE (sysdate - hire_date) YEAR TO MONTH > get_time_work (114);



  • как аргумент в списке параметров другой программной единицы, например:

BEGIN
CHANGE_HIRE_DATE (105, get_time_work (107)); END;


/

где CHANGE_HIRE_DATE – гипотетическая процедура для изменения даты приема на работу сотрудника.


Функции, которые в результате своей работы производят изменения в БД, нельзя применять в SQL-запросах.
Просмотреть существующие процедуры и функции можно с помощью запроса к словарю данных:
SELECT OBJECT_NAME, OBJECT_TYPE, STATUS FROM USER_OBJECTS
WHERE OBJECT_TYPE IN ('PROCEDURE', 'FUNCTION');
Пакеты. Процедуры и функции можно группировать в пакеты. Пакеты инкапсулируют связанные функциональности в один автономный модуль.
Пакет состоит из двух компонентов:

    • спецификация,

    • тело.

Спецификация перечисляет все имеющиеся в пакете процедуры, функции, типы и объекты. Можно сделать их доступными для всех пользователей, у которых есть доступ к пакету. Сам код процедур и функций спецификация не содержит.
Тело пакета содержит сам код процедур и функций, которые объявлены в спецификации. Любая процедура или функция, содержащаяся в теле пакета и не упомянутая в спецификации, будет доступна только внутри тела пакета.
Создание спецификации пакета:
CREATE [OR REPLACE] PACKAGE имя_ пакета
{IS | AS}
спецификация пакета END имя_пакета;
Создание тела пакета:
CREATE [OR REPLACE] PACKAGE BODY имя_ пакета
{IS | AS}
тело пакета
END имя_пакета;
Обращение к процедурам и функциям пакета происходит посредством точечной нотации.
Локальные модули. Локальный модуль – это процедура или функция, кото- рая определена в разделе объявления переменных блока PL/SQL. Использование локальных модулей повышает модульность программы, уменьшает объем кода и улучшает читабельность программы. Локальным такой модуль называется по причине того, что он доступен только для использования внутри блока, где он объявлен. Вернемся к процедуре изменения заработной платы и перепишем ее:
CREATE OR REPLACE PROCEDURE CHANGE_SALARY2
(empId IN NUMBER, newsal IN NUMBER) IS
TYPE EMP_INF_TYPE IS RECORD (
job_id employees.job_id%TYPE :=0, salary employees.salary%TYPE := 0, min_sal employees.salary%TYPE := 0, max_sal employees.salary%TYPE := 0);
empInf EMP_INF_TYPE;
FUNCTION getInf (emp_id in Number) return EMP_INF_TYPE
IS
result EMP_INF_TYPE; BEGIN
SELECT emp.job_id, emp.salary, jobs.min_salary, jobs.max_salary INTO result FROM employees emp, jobs
WHERE employee_id = empId AND emp.job_id = jobs.job_id; RETURN result;
END getInf;
FUNCTION TestSalary (empInf IN EMP_INF_TYPE, newsal IN Number) RETURN BOOLEAN
IS BEGIN
IF newsal < empInf.min_sal OR newsal > empInf.max_sal THEN RETURN FALSE;
ELSE RETURN TRUE; END IF;
END TestSalary;
BEGIN
empInf :=getInf (empId);
IF TestSalary(empInf, newsal) THEN
UPDATE employees SET salary = newsal WHERE employee_id = empId; COMMIT;
DBMS_OUTPUT.PUT_LINE ('Сотрудник '||empID||': старая заработная плата = '|| empinf.salary||',
новая заработная плата = '||newsal);
ELSE DBMS_OUTPUT.PUT_LINE('Сумма вне рамок должностного оклада'); END IF;
END;
/


В примере используется две локальные функции: getInf, которая возвращает в переменную типа запись информацию о сотруднике и TestSalary, которая прове- ряет, входит ли новая заработная плата в допустимые по должности рамки.
Перегрузка модулей. Программы, которые существуют в одной и той же области видимости и имеют одинаковые имена, называются перегруженными.

DECLARE
val_s VARCHAR2 (50) := 'выводим текстовую строку'; val_n NUMBER := 452.36;


val_d DATE := SYSDATE;
PROCEDURE mywrite (VALUE IN VARCHAR2) IS BEGIN
DBMS_OUTPUT.PUT_LINE ('значение переменной =''' || VALUE || '''='); END;
PROCEDURE mywrite (VALUE IN NUMBER) IS
s VARCHAR2 (20) := TO_CHAR (VALUE, '99999.99'); BEGIN
DBMS_OUTPUT.put_line ('значение переменной =' || s); END;
PROCEDURE mywrite (VALUE IN DATE) IS
s VARCHAR2 (20):= TO_CHAR (VALUE, 'dd.mm.yyyy hh:mi'); BEGIN
DBMS_OUTPUT.PUT_LINE ('значение переменной =' || s); END;
BEGIN
mywrite (val_s); mywrite (val_n); mywrite (val_d); END;
/

Перегрузка является подходящим решением при необходимости под- держки разных типов данных. Использование перегрузки имеет несколько ограничений. PL/SQL должен иметь возможность отличить друг от друга раз- ные модули, имеющие одно и то же имя. Для этого используют списки пара- метров и/или сведения о подпрограмме (процедура или функция). Если у пере- груженных подпрограмм отличаются только имена параметров, то такие под- программы должны вызываться только с использованием метода связывания параметров по имени. Все перегруженные подпрограммы должны быть объяв- лены в одном и том же блоке PL/SQL.






Достарыңызбен бөлісу:
1   ...   12   13   14   15   16   17   18   19   ...   56




©emirsaba.org 2024
әкімшілігінің қараңыз

    Басты бет