Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Fondovi-lekcii.doc
Скачиваний:
20
Добавлен:
10.11.2018
Размер:
4.09 Mб
Скачать

1.2. Цикли й оператори розгалуження.

Основна проблема "вбудовування" речення SELECT в процедуру полягає в тому, що SELECT, як правило, породжує таблицю з множиною рядків і стовпців, а включаюча мова не має засобів, що дозволяють оперувати одночасно більш ніж одним записом. З цієї причини необхідно забезпечити міст між рівнем множин мови SQL і рівнем записів процедури.

Для цього використовується одиничне SELECT, формат якого має вид

SELECT { * | элемент_select [, элемент_select] ...}

INTO змінна [, змінна] ...

FROM базова_таблиця [, базова_таблиця] ...

[WHERE умова ];

Очевидно, що цей опис відрізняється від стандартного підзапиту наявністю фрази INTO і включенням змінних.

Наведемо приклад. Одержати загальну вагу продуктів на складі і занести її в змінну Загальна_вага:

SELECT SUM(Кількість)

INTO Загальна_вага

FROM Склад;

Якщо запит повертає більш одного рядка, то його необхідно оформити у виді конструкції FOR SELECT...DO, що організує цикл для обробки кожного рядка, що повертається.

FOR

SELECT ID, NAME, PRICE_1

FROM Table_Example

INTO :ID, :NAME, :new_price

DO

BEGIN

/*тут обробляємо кожен запис*/

END

Зверніть увагу, що змінні ID, NAME, new_price випереджаються двокрапкою – для того, щоб відрізнити їх від полів, що використовуються у запиті.

Крім команди FOR SELECT... DO, що організує цикл по записах будь-якої вибірки, існує інший вид циклу – WHILE...DO, що дозволяє організувати цикл на основі перевірки будь-яких умов. Ось приклад ЗП, що використовує цикл WHILE. ..DO. Ця процедура повертає квадрати цілих чисел від 0 до 99:

CREATE PROCEDURE QUAD

RETURNS (QUADRAT INTEGER)

AS

DECLARE VARIABLE I INTEGER;

BEGIN

I=1

WHILE (i<100) DO

BEGIN

QUADRAT = I*I;

SUSPEND;

END

END

Крім перебору результатів SQL-вибірки і класичного циклу, у мові збережуваних процедур використовується оператор IF...THEN..ELSE, що дозволяє організувати розгалуження в залежності від виконання яких-небудь умов.

Давайте розглянемо більш складний приклад збережуваної процедури, що робить наступне:

1. Обчислює середню ціну в таблиці Table_example.

2. Далі для кожного запису в таблиці робить наступну перевірку: якщо існуюча ціна (PRICE) більше середньої ціни, то встановлює ціну, рівну величині середньої ціни, плюс фіксований відсоток, що задається.

3. Якщо існуюча ціна рівна чи менша середньої ціни, то встановлює ціну, рівну колишній ціні, плюс половина різниці між колишньою і середньою ціною.

4. Повертає всі змінені рядки в таблиці.

Збережувана процедура, що реалізує це завдання має вид:

CREATE PROCEDURE IncreasePrices (Percent2Increase DOUBLE PRECISION) RETURNS (ID INTEGER, NAME VARCHAR(8O), 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_price > avg__price) THEN

/*якщо існуюча ціна більше середньої ціни*/

BEGIN

/*установимо нову ціну, рівну величині середньої ціни, плюс

фіксований відсоток */

new_price = (avg_price + avg_price*(Percent2Increase/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

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]