Oracle PL/SQL (Procedural Language / Structured Query Language) Процедурное расширение декларативного языка SQL, обеспечивающее императивный стиль программирования ( полный по Тьюрингу) Поддерживается: Oracle Database (начиная с версии 7) Oracle Application Express Oracle Developer Suite IBM DB2(начиная с версии 9.7) Язык PL/SQL позволяет использовать: переменные, операторы, массивы, курсоры, исключения, процедуры, функции, пакеты объекты (начиная с версии 8); Словарь спецификаций • • • • • • Основной разделитель слов: пробел Дополнительные разделители: Tab и <Перевод строки> Ограничитель последовательности слов: ; Строковый комментарий : -Многострочный комментарий: /* comment */ Идентификатор: начинается с буквы, регистры не различаются, длина до 30 символов, не ключевое слово ( salary = Salary = SALARY, но “salary” != “SALARY”) • Вещественные числа – числовой литерал: 0.25 • Символ присваивания := cnt := cnt +1; -- верный оператор cnt : = cnt+1; -- неверный оператор, пробел после двоеточия Специальные символы Обозначение Операция +, -, *, / Сложение, вычитание, умножение, деление ** Возведение в степень =, >, <, <=, >=, <>, !=, ^=, ~= Сравнение на равно, больше, меньше, больше либо равно, меньше либо равно, неравно(4 варианта) () Изменение порядка выполнения арифметических или логических операций ‘ ‘ Символьная строка || Конкатенация символьных строк % Указатель атрибута @ Удаленный доступ . Разделитель составного слова .. Диапазон значений Типы данных Встроенные(стандартные) • NUMBER(целая часть, дробная часть) DECIMAL FLOAT INTEGER подтипы числового NUMBER REAL SMALLINT и др. • CHAR(фикс. длина) – символьный фиксированный • VARCHAR2(максим. длина) – символьный переменной длины • BLOB(CLOB) – объектный • BOOLEAN – логический • DATE – дата, время Функции преобразования TO_DATE(char или number), TO_NUMBER(char), TO_CHAR(date или number ) Структурный тип данных SQL Пользовательский(создаваемый) • • • Объект CREATE TYPE имя IS OBJECT (список полей и их типов); Таблица CREATE TYPE имя IS TABLE OF тип данных ; Массив коллекции CREATE TYPE имя IS ARRAY(VARRAY) OF тип данных; Пример создания таблицы с атрибутами стандартного и структурных типов Create type node is object( a varchar2(10), b number(12,5), c integer); Create type list is table of node; Create table t(atr1 integer, atr2 node, atr3 list); Atr1 Atr2 Atr3 1 (‘abc’,12.45,28) (‘dddd’,13.4,1) (‘mmm’,23.4,2) (‘uuu’,44.2,123) Структурный тип данных в PL/SQL • • • Запись TYPE имя IS RECORD (список полей и их типов); Таблица TYPE имя IS TABLE OF тип данных ; Массив TYPE имя IS VARRAY(max) OF тип данных; Пример …. TYPE type1 is record(a integer, b varchar2(10)); TYPE type2 is table of date; my_record type1; my_collection type2; …… my_record .a := 1; my_record.b := ‘aaaaaa’; my_collection := type2(SYSDATE,SYSDATE-1,SYSDATE-2); dbms_output.put_line(my_record.b|| ‘ ‘||my_collection(3)); my_collection.delete(3); dbms_output.put_line(my_collection(1)|| ‘ ‘||my_collection(2)); …… Объявления Статические идентификатор тип_данных [свойства] [инициализация]; Примеры: newdate DATE; stroka VARCHAR2(5) NOT NULL := ‘abcde’; pi CONSTANT REAL := 3.14; Мобильные идентификатор объект_наследования_типа % TYPE [свойства] [инициализация]; идентификатор объект_наследования_типа % ROWTYPE [свойства] [инициализация]; Примеры: stroka PERSONA.FIO%TYPE; abc_rec ABC_OBJECT%ROWTYPE; Структура программного блока DECLARE -- Описания блока, переменные, типы, курсоры и т. п. BEGIN -- Непосредственно код программы EXCEPTION -- Обработка исключений END; Пример выполняемого блока set serveroutput on; --включить отклик сервера declare stoka varchar2(50) := ‘Hello, Oracle!’; begin dbms_output.put_line(stroka); --функция выдачи текста на экран end; Условные операторы IF - THEN - END IF; IF - THEN - ELSE - END IF; IF - THEN - ELSIF - END IF; IF - THEN - ELSIF - ELSE - END IF; Пример: If rating between 100 and 200 then bonus := 15; else bonus := 5; end if; CASE - WHEN - THEN - END CASE; CASE - WHEN - THEN - ELSE - END; Пример: CASE flag WHEN TRUE THEN 'True' WHEN FALSE THEN 'False' ELSE 'NULL' END; Операторы цикла Безусловный (LOOP - END LOOP) Пример: i integer := 1; …… LOOP dbms_output.put_line(‘i= ‘ ||to_char(i)); i:= i+1; EXIT WHEN i>10; END LOOP; С предусловием (WHILE - LOOP - END LOOP) Пример: i integer := 1; …… WHILE i<=10 LOOP dbms_output.put_line(‘i= ‘ ||to_char(i)); i:= i+1; END LOOP; Операторы цикла Диапазон (FOR - LOOP - END LOOP) Пример: i integer; …… FOR i IN 1..10 LOOP dbms_output.put_line(‘i= ‘ ||to_char(i)); END LOOP; Оператор безусловного перехода GO TO метка; Пустой оператор NULL; Процедуры CREATE [OR REPLACE] PROCEDURE имя (имя_пар1 [in|out|in out] тип,…..) IS описание_локальных_переменных BEGIN --последовательность операторов EXCEPTION -- обработка исключений END имя; Пример процедуры Create or replace procedure calc_bonus( id_local in person.id%TYPE, bonus out person.sal%TYPE) IS salary person.sal%TYPE := 0.0; BEGIN Select Person.sal into salary from person where person.id = id_local; if salary != 0.0 then bonus := salary* 0.15; else bonus :=-1; end if; EXCEPTION WHEN NO_DATA_FOUND THEN dbms_output.put_line('Error ID !'); bonus := 0.0; END calc_bonus; Функции CREATE [OR REPLACE] FUNCTION имя (имя_пар1 [in] тип,…..) RETURN тип_возвращаемого_значения IS описание_локальных_переменных BEGIN --последовательность операторов EXCEPTION -- обработка исключений END имя; Пример функции Create or replace function count_person( salary in person.sal%TYPE ) RETURN integer IS count_salary integer := 0; no exception; BEGIN select count(*) into count_salary from person where person.sal > salary; if count_salary = 0 then raise no; else end if; return count_salary; EXCEPTION WHEN NO THEN dbms_output.put_line('No DATA !'); return -1; END count_person; Триггеры CREATE [OR REPLACE] TRIGGER имя [BEFORE|AFTER] [INSERT |OR| UPDATE|DELETE] ON имя_таблицы FOR EACH ROW [WHEN условие] DECLARE -- описание_локальных_переменных BEGIN --последовательность операторов EXCEPTION -- обработка исключений END имя; Пример триггера Create or replace trigger cheker BEFORE UPDATE ON person for each row declare BEGIN if :new.sal < :old.sal then raise_application_error(-20125,'New salary must be more then old salary'); end if; end cheker; Курсоры Простой CURSOR имя IS запрос Пример: cursor c1 is select sal from person where person.id = enter; Параметрический CURSOR имя (пар1 тип1, пар2 тип2, ….) IS запрос Пример: cursor c2 (enter in integer) is select sal from person where person.id = enter; Возвращающий данные CURSOR имя RETURN таблица%ROWTYPE IS запрос Пример: cursor c3 return persona%ROWTYPE is select * from person where person.id = 1; Операторы и атрибуты курсора Операторы OPEN имя_курсора [параметры] - открытие курсора(инициализация) CLOSE имя_курсора – закрытие курсора FETCH имя_курсора INTO переменные – выбор очередной строки данных Атрибуты %FOUND – истина, если FETCH вернул строку %NOTFOUND – истина, если FETCH не вернул строку %ISOPEN –истина, если курсор открыт %ROWCOUNT – количество возвращенных строк(активного множества) Пример курсора declare CURSOR c1 IS SELECT sal FROM person; summa person.sal%TYPE := 0.0; salary person.sal%TYPE; BEGIN OPEN c1; loop FETCH c1 INTO salary; EXIT WHEN c1%notfound; summa := summa + salary; end loop; CLOSE c1; dbms_output.put_line(to_char(summa)); END;