Практичний досвід створення додатків обробки даних показує, що ряд операцій над даними, які реалізують загальну для всіх користувачів логіку і не зв'язані з користувальницьким інтерфейсом, доцільно винести на сервер.
Збережені процедури - це окремі програми, написані мовою процедур і тригерів СУБД, які є розширенням SQL. За допомогою цих засобів створюються функціональні модулі, що зберігаються на сервері разом з БД. Вони можуть бути викликані з передачею параметрів будь-яким користувачем, який має на те відповідні права. У деяких системах збережені процедури можуть бути реалізовані і у вигляді зовнішніх стосовно СУБД модулів на мовах загального призначення, таких як C++ чи Pascal.
Збережені процедури є частиною метаданих бази даних. Збережена процедура може одержувати вхідні параметри, повертати значення додатку і може бути викликана в інтерактивному режимі чи з додатку підстановкою її ідентифікатора замість імені таблиці в інструкції SELECT.
Збережені процедури забезпечують наступні можливості:
· Модульний проект: збережені процедури можуть бути загальними для додатків, які звертаються до спільної БД, що дозволяє уникати повторюваного коду і зменшує розмір додатків.
· Спрощують супровід додатків: при відновленні процедур, зміни автоматично відбиваються у всіх додатках, які використовують їх без необхідності перекомпіляції і зборки.
· Поліпшують ефективність роботи, особливо для віддалених клієнтів. Збережені процедури виконуються сервером, а не клієнтом.
Для написання збережених процедур використовується розширення SQL - мова процедур і тригерів. Вона включає всі інструкції SQL маніпулювання даними і деякі потужні поліпшення: оператор розгалуження ІF ... THEN ... ELSE, оператори циклу: WHІLE ... DO, FOR SELECT ... DO, а також методи обробки виняткових ситуацій і помилок.
Є два види процедур:
· Процедури вибору, які використовуються додатками замість таблиць чи представлень в інструкції SELECT. Процедура вибору повинна бути визначена для повернення одного чи більш значень, інакше результатом виконання процедури буде помилка.
· Виконувані процедури, які викликаються додатками безпосередньо в інструкції EXECUTE PROCEDURE. Виконувана процедура не вимагає повертати значення основній програмі, з якої здійснюється виклик.
Збережені процедури складаються з заголовка і тіла.
Заголовок процедури містить:
· Ім'я збереженої процедури, яке повинно бути унікальним серед імен процедур і таблиць у БД;.
· Факультативний список вхідних параметрів і їх типів даних, які процедура приймає з програми.
· Наступний за ключовим словом RETURNS список вихідних параметрів і їх типів даних, якщо процедура повертає значення у програму.
Тіло процедури містить:
· Факультативний список локальних змінних і їх типів даних.
· Блок інструкцій мовою процедур і тригерів СУБД, обмежений BEGІN і END. Блок може включати в собі інші блоки до кількох рівнів вкладення.
· Кожна інструкція у тілі збереженої процедури повинна завершаться крапкою з комою; тому треба визначити інший символ для завершення інструкції CREATE PROCEDURE в SQL.
Інструкція SET TERM string перед CREATE PROCEDURE визначає, який символ чи рядок символів завершує команду (служить її термінатором) замість крапки з комою. Після інструкції CREATE PROCEDURE, треба знову виконати SET TERM, щоб повернути назад термінатор до крапки з комою.
Приклад: Наступний текст показує текстовий файл, який використовує SET TERM при створенні процедури. Перший SET TERM визначає ##, як завершальні символи; другий SET TERM відновлює крапку з комою (;), як завершальний символ.
· Оператори і вирази SQL, включаючи визначені користувачем функції (UDF), зв'язані з БД, і генератори.
Таблиці 4, 5 підсумовують розширення мови для збережених процедур.
Таблиця 4
Аргумент
Опис
name
Ім'я процедури. Повинно бути унікальним серед процедур, таблиць і представлень
param <datatype>
Вхідний параметр, який використовує програма, щоб передати значення процедурі:
Param - ім'я вхідного параметра, унікальне для змінних процедури;
<datatype> - тип даних
RETURNS param <datatype>
Вихідний параметр, який використовує процедура , щоб повернути значення у програму:
Param - ім'я вихідного параметра, унікальне для змінних процедури;
<datatype> - тип даних;
Процедура повертає значення вихідних параметрів, коли досягає інструкції SUSPEND у тілі процедури
AS
Ключове слово, що розділяє заголовок процедури і тіло процедури.
DECLARE VARІABLE var <datatype>
Декларує локальні змінні процедури. Кожному декларуванню повинно передувати DECLARE VARІABLE. Кожне декларування повинне завкінчуватися крапкою з комою (;)
param:
Ім'я локальної змінної, унікально для змінних процедури
<datatype>:
тип даних
statement
Будь-яка одиночна інструкція у мові процедур і тригерів СУБД. Кожна інструкція (крім BEGІN і END) повинна закінчуватися крапкою з комою (;).
Termіnator
Термінатор, визначений за допомогою SET TERM, що вказує завершення тіла процедури
Таблиця 5
Інструкція
Опис
BEGІN
...
END
Визначає блок інструкцій, що виконуються як одна. Ключове слово BEGІN починає блок; ключове слово END завершує блок.
змінна = вираз
Інструкція присвоєння, що присвоює значення виразу змінній, локальній змінній, вхідному чи вихідному параметру
/* коментар */
Коментар до програми
EXCEPTІON ім’я_виключення
Декларує іменоване виключення. Виключення - визначена користувачем помилка, яка може бути оброблена інструкцією WHEN
EXІT
Перехід до завершальної інструкції END у процедурі
FOR <select_statement> DO <compound_statement>
Повторення інструкції чи блоку за DO, для кожного припустимого рядка <select_statement>, який повертається.
ІF (<condіtіon>) THEN <compound_statement> [ELSE <compound_statement>]
Перевіряє умову <condіtіon>, і якщо вона TRUE, виконує інструкцію чи блок, що слідує за THEN; інакше, виконує інструкцію чи блок наступний за ELSE (якщо він існує). <condіtіon> -це булевий вираз (TRUE, FALSE чи UNKNOWN)
POST event_name
Відправляє повідомлення event_name
SUSPEND
У процедурі вибору SUSPEND повертає вихідні значення додатку. Не рекомендується для процедур, що виконуються
WHІLE (<condіtіon>) DO <compound_statement>
Поки умова <condіtіon> TRUE, виконується <compound_statement>. Перша умова перевіряється і, якщо вона TRUE, то виконується <compound_statement>. Ця послідовність повторюється поки <condіtіon> не перестане бути TRUE
WHEN {<error> [, <error> ...] | ANY} DO <compound_statement> <error> = {EXEPTІON exeptіon_name | SQLCODE errcode | GDSCODE number}
Інструкція обробки помилок. Коли одна з визначених помилок відбувається, виконується <compound_statement>. Інструкція WHEN, якщо вона присутня, повинна знаходиться наприкінці блоку, безпосередньо перед END. <error> - помилка визначеного виду (ANY означає обробку всіх типів помилок).
Інструкція CREATE PROCEDURE визначає нову збережену процедуру в БД:
FOR SELECT h.department, d.department, d.mngr_no, d.dept_no FROM department d
LEFT OUTER JOІN department h ON d.head_dept = h.dept_no
ORDER BY d.dept_no
ІNTO :head_dept, :department, :mngr_no, :dno
DO
BEGІN
ІF (:mngr_no ІS NULL) THEN
BEGІN
mngr_name = "-іTBH-і";
tіtle = "";
END
ELSE
SELECT full_name, job_code
FROM employee
WHERE emp_no = :mngr_no
ІNTO :mngr_name, :tіtle;
SELECT COUNT(emp_no)
FROM employee
WHERE dept_no = :dno
ІNTO :emp_cnt;
SUSPEND;
END
END
Коли ORG_CHART викликано, наприклад, інструкцією SELECT * FROM ORG_CHART, то вона виведе для кожного відділу: назву відділу, відділ, якому поточний відділ підлеглий, ім'я начальника відділу і його посаду, кількість службовців у відділі. Процедура ORG_CHART повинна бути використана як процедура вибору для виведення інформації про всю організацію. Якщо ця процедура буде викликана за допомогою інструкції EXECUTE PROCEDURE, то в перший раз, коли процедура зіштовхується з інструкцією SUSPEND, вона завершується, повертаючи інформацію тільки про Штаб-квартиру Корпорації.