Lab_04_Oracle %28PL_SQL%29 / Додатково_Теорія_01_Блоки_керуючі_структури_ PL_SQL
.pdf13INSERT INTO "СООБЩ" ("ЧИСЛО1","СИМВОЛ1") VALUES
(i+j,'тест');
14ROLLBACK;
15j := j + 1;
16END LOOP;
17END LOOP main;
18END;
19/
Ітерація зовнішнього циклу №1 Ітерація зовнішнього циклу №2 Ітерація зовнішнього циклу №3
Процедура PL/SQL успішно завершена.
15. Запис в PL/SQL і атрибут %ROWTYPE
Запис в PL/SQL є змінною, котра може містити набір окремих значень, при цьому кожне з них індивідуально пойменоване. Компоненти запису називаються полями й мають свої імена, використовувані для посилання на них у вираженнях і операторах присвоювання. Поля запису можуть мати різні типи даних і розміри, як стовпці в таблиці БД. Це значить, що записи дуже зручні для зчитування рядків з таблиці БД у програму PL/SQL.
Для оголошення запису на основі опису таблиці або подання застосовується атрибут %ROWTYPE. Поля запису одержують ті ж імена, що й імена стовпців відповідної таблиці або подання.
Записи оголошуються в секції DECLARE блоку поряд з іншими типами змінних, у такий спосіб:
ідентифікатор посилання%ROWTYPE;
де «ідентифікатор» – це ім'я декларованого запису, а «посилання» – ім'я таблиці, подання або зовнішнього курсору, на основі структури якого створюється структура запису. Це посилання повинне бути коректним на момент оголошення запису (тобто таблиця або подання повинні існувати й бути доступними). Поля запису можуть задаватися індивідуально як у командах PL/SQL, так і у декларації блоку SQL-Команд.
У наведеному нижче прикладі запис «rec» складається з полів, аналогічних стовпцям таблиці СЛУЖ:
SQL> SET SERVEROUTPUT ON SQL> DECLARE
2total NUMBER(10,2);
3rec служ%ROWTYPE;
4BEGIN
5SELECT * INTO rec FROM служ WHERE служ_номер = 7499;
6DBMS_OUTPUT.enable;
7 |
DBMS_OUTPUT.put_line('Номер відділу: |
' || rec.відділ_номер); |
8 |
DBMS_OUTPUT.put_line('Номер співробітника: ' || |
|
rec.служ_номер); |
|
|
9 |
DBMS_OUTPUT.put_line('Прізвище: |
' || rec.служ_ім'я); |
10DBMS_OUTPUT.put_line('Дата надходження: ' || rec.надійшов);
11DBMS_OUTPUT.put_line('Номер керівника: ' || rec.менеджер);
12DBMS_OUTPUT.put_line('Спеціальність: ' || rec.робота);
13 |
DBMS_OUTPUT.put_line('Оклад: |
' || rec.оклад); |
14 |
DBMS_OUTPUT.put_line('Премія: |
' || rec.премія); |
15total := rec.оклад + NVL(rec.премія,0);
16SAVEPOINT point;
17INSERT INTO сообщ (число1, символ1)
18VALUES (total, rec.служ_ім'я);
19ROLLBACK TO point;
20 DBMS_OUTPUT.put_line('Разом: |
' || total || ' гр.'); |
|
21 END; |
|
|
22/ |
|
|
Номер відділу: |
30 |
|
Номер співробітника: 7499 |
|
|
Прізвище: |
ІВАНОВА |
|
Дата надходження: 20.02.99 |
|
|
Номер керівника: 7698 |
|
|
Спеціальність: |
РЕАЛИЗАТОР |
|
Оклад: |
1600 |
|
Премія: |
300 |
|
Разом: |
1900 гр. |
|
Процедура PL/SQL успішно завершена.
Можливе присвоєння цілком вмісту одного запису іншим за умови, що записи мають аналогічну структуру. Ім'я запису, проте, не може бути зазначене в пропозиції VALUES команди INSERT. Кожний її елемент повинен бути зазначений індивідуально, наприклад:
SQL> SET SERVEROUTPUT ON SQL> DECLARE
2rec1 відділ%ROWTYPE;
3rec2 відділ%ROWTYPE;
4rec3 відділ%ROWTYPE;
5BEGIN
6rec1.відділ_номер := 50;
7rec1.відділ_ім'я := 'ТЕСТУВАННЯ';
8rec1.розташований := 'ЛУГАНСЬК';
9rec2 := rec1;
10SAVEPOINT point;
11INSERT INTO відділ (відділ_номер, відділ_ім'я, розташований)
12VALUES (rec2.відділ_номер, rec2.відділ_ім'я,
rec2.розташований);
13SELECT * INTO rec3 FROM відділ WHERE відділ_номер = 50;
14ROLLBACK TO point;
15DBMS_OUTPUT.enable;
16DBMS_OUTPUT.put_line('Номер відділу: ' || rec3.відділ_номер);
17DBMS_OUTPUT.put_line('Спеціалізація: ' || rec3.відділ_ім'я);
18DBMS_OUTPUT.put_line('Локалізація: ' || rec3.розташований);
19END;
20/
Номер відділу: 50 Спеціалізація: ТЕСТУВАННЯ Локалізація: ЛУГАНСЬК
Процедура PL/SQL успішно завершена.
У PL/SQL версії 2 і вище дозволяє користувачеві також повідомляти свої власні записи незалежно від структури таблиць. У цих «записах, які задаються користувачем», він сам може іменувати й задавати тип кожного з полів запису.
16. Анонімні блоки (сценарії SQL)
Анонімний блок PL/SQL – це неіменована програма, що використовується для налагодження текстів програм інших видів. Досить часто анонімні блоки називають сценаріями SQL.
DECLARE -- декларативна частина анонімного блоку -- опис локальних змінних
tekst VARCHAR2(20) := 'Жан - Жак Руссо'; -- Присвоюється текст, -- як (прізвище, ім'я або по батькові)
vychod VARCHAR2(20); -- Результат (перевірений і може бути -- виправлений вхідний текст або "0 "при непоправній помилці) kol INTEGER; -- Кількість символів у перевіряємому тексті
BEGIN -- виконується тіло анонімного блоку vychod := LOWER(RTRIM(LTRIM(tekst)));
--перший варіант результату,
--отриманий після видалення із вхідного тексту початкових
--(LTRIM) і
--кінцевих (RTRIM) пробілів, а також перетворення всіх букв --тексту в рядкові (LOWER)
kol := LENGTH(vychod); -- визначення числа символів, що
--залишилися в тексті
--після видалення початкових і кінцевих пробілів
IF kol > 0 THEN -- якщо текст містить символи, те його подальше -- перетворення й перевірка на наявність заборонених символів vychod := REPLACE(vychod,' ',' '); -- заміна двох пробілів на один vychod := REPLACE(vychod,'- ','-'); -- заміна тире й пробілу на тире vychod := REPLACE(vychod,' -','-'); -- заміна пробілу й тире на тире kol := LENGTH(vychod); -- визначення числа символів, що
-- залишилися в тексті
FOR i IN 1..kol LOOP -- перебір всіх символів тексту IF INSTR('- абвгдеежзийклмнопрстуфхцчшщъыьэюя',
SUBSTR(vychod,i,1)) = 0
THEN
--за допомогою функції INSTR визначається позиція першого
--включення
--i-го символу тексту (вирізаного за допомогою функції
--SUBSTR) в
--набір '- абвгдеежзийклмнопрстуфхцчшщъыьэюя' і якщо ця
--позиція
--дорівнює 0 ( i-го символу немає в наборі), те виробляється: vychod := '0'; -- установка нульового результату й
EXIT; -- вихід із циклу
END IF;
END LOOP; ELSE
vychod := '0'; -- установка нульового результату при відсутності -- в тексті символів, відмінних від пробілів
END IF;
IF vychod <> '0' THEN -- якщо текст містить символи, то: vychod := INITCAP(vychod);
-- перетворення перших букв слів тексту в прописні
END IF; DBMS_OUTPUT.PUT_LINE(vychod);
--використання утиліти DBMS_OUTPUT пакета
--DBMS_STANDARD для виводу на термінал
--результату перетворення
END;
/ -- похила риска, що вказує на закінчення тексту блоку PL/SQL
Цей анонімний блок можна ввести за допомогою текстового редактора у файл (наприклад, з ім'ям an_fio.sql) або вводити рядок за рядком прямо в SQL*Plus. В останньому випадку уведення в першому рядку одного із зарезервованих слів DECLARE або BEGIN переводить SQL*Plus у режим порядкового введення рядків анонімного блоку так, як це показано нижче.
SQL> DECLARE -- декларативна частина анонімного блоку
2 |
|
-- опис локальних змінних |
3 |
tekst VARCHAR2(20) := 'Жан - Жак Руссо'; |
|
|
-- |
Присвоюється текст, що (прізвище, |
4 |
-- |
ім'я або по батькові) |
5 |
vychod VARCHAR2(20); |
|
-- Результат (перевірений і може бути виправлений |
6 -- |
вхідний текст або "0 "при непоправній помилці) |
7 |
kol INTEGER; -- Кількість символів перевіряється в тексті |
8BEGIN -- виконується тіло анонімного блоку
9vychod := LOWER(RTRIM(LTRIM(tekst)));
--перший варіант результату,
. . .
44 END; 45/
Після введення похилої риси блок виконується й на екран видаєть-ся результат його роботи:
Жан-Жак Руссо
Процедура PL/SQL успішно завершена.
SQL> _
Якщо текст анонімного блоку був збережений у файлі an_fio.sql, то такий сценарій SQL можна виконати за допомогою команди @an_fio.sql або @an_fio (розширення .sql, що вказує, що даний файл є файлом запиту, можна опустити):
SQL> @an_fio
Жан-Жак Руссо
Процедура PL/SQL успішно завершена.
SQL> _
Якщо будуть утруднення у виборі типів даних рекомендується розібрати приклади, характерні для наведеного прикладу анонімного блоку.
17. Типи даних, змінні, константи й вирази. Типи даних, доступні в PL/SQL
Крім типів даних Oracle PL/SQL підтримує кілька додаткових типів
даних: |
|
Тип даних |
Опис |
BINARY_INTEGER |
Цей тип даних і його підтипи NATURAL |
|
і |
POSITIVE |
застосовуються для |
|
|
створення змінних і констант, які |
|||
|
зберігають число зі знаком. |
|||
|
Двійкові цілі числа можуть приймати |
|||
|
значення в діапазоні від -2 в 31 ступені |
|||
|
до 2 в 31 ступені мінус 1. |
|||
BOOLEAN |
Приймається для створення змінних і |
|||
|
констант, у яких зберігаються логічні |
|||
|
значення TRUE і FALSE. |
|||
CHAR |
Є підтипи CHARACTER і STRING. |
|||
|
Максимальний розмір 32767. |
|||
NUMBER |
Є підтипи DEC, DECIMAL, DOUBLE |
|||
|
PRECISION, INT, INTEGER, |
|||
|
REAL,NUMERIC, і SMALLINT |
|||
RECORD |
Використовується для створення ко- |
|||
|
ристувальницьких типів записів. |
|||
TABLE |
Служить |
для |
створення табличних |
|
|
типів даних PL/SQL. |
|||
VARCHAR2 |
Є |
підтип |
VARCHAR. Максимальний |
|
|
розмір 32767. |
|
||
col%TYPE |
Використовується для визначення типу |
|||
|
даних стовпця або змінної за типом |
|||
|
даних іншого стовпця або змінної, до |
|||
|
ім'я якого або якої (col) приписаний |
|||
|
суфікс %TYPE. |
|
||
tab%ROWTYPE |
Використовується для визначення типу |
|||
|
даних запису за типом даних стовпців |
|||
|
таблиці, до ім'я якої (tab) приписаний |
|||
|
суфікс %ROWTYPE. |
18. Таблиці PL/SQL
Таблиця PL/SQL – це одномірний масив з необмеженою кількістю рядків. Для оголошення цього масиву (таблиці PL/SQL або TABLE) необхідно спочатку визначити тип його даних:
TYPE type_name IS TABLE OF { column_type | variable%TYPE |
table.column%TYPE } [NOT NULL] INDEX BY BINARY_INTEGER;
де "type_name" – специфікатор типу, використовуваний у наступних оголошеннях таблиць PL/SQL, і "column_type" – кожної зі скалярних типів даних: CHAR, DATE або NUMBER. За допомогою атрибута %TYPE можна встановити "type_name" відповідному типу даних якої-небудь змінної
(variable) або стовпця (table.column).
Ім'я (наприклад, name_plsql_table), що описується табличним типом даних, називається таблицею PL/SQL. Це опис, розташовуваний у розділі
DECLARE, має вигляд:
name_plsql_table type_name;
Посилання на рядки таблиці PL/SQL здійснюються аналогічно посиланням на елементи одномірного масиву:
name_plsql_table(index) ,
де index належить типу BINARY_INTEGER. Наприклад, для посилання на третій рядок у таблиці PL/SQL "ename_tab" варто написати: ename_tab(3).
Для присвоєння значення конкретному рядку таблиці PL/SQL використовується синтаксис:
name_plsql_table(index) := expr;
Для введення в таблицю PL/SQL значень із якого-небудь стовпця базової таблиці або подання, а також для вибірки значень із таблиці PL/SQL, необхідно використовувати цикл. (Приклади таких операцій наведені нижче.)
19. Записи PL/SQL
Record PL/SQL – це сукупність полів, кожне з яких повинне мати унікальне ім'я (у межах запису). Ці поля можуть належати різним типам даних.
Якщо створюваний запис (stud) відповідає опису стовпців якої-небудь базової таблиці (наприклад, studenty), то її оголошення можна здійснити в розділі DECLARE за допомогою атрибута %ROWTYPE:
stud studenty%ROWTYPE;
У протилежному випадку для оголошення запису необхідно спочатку визначити її тип даних. Для опису типу даних RECORD використовується синтаксис:
TYPE type_name IS RECORD
( field_name1 {field_type | variable%TYPE | table.column%TYPE | table%ROWTYPE} [NOT NULL],
field_name2 {field_type | variable%TYPE | table.column%TYPE | table%ROWTYPE} [NOT NULL],
...) ;
де "type_name" – специфікатор типу, використовуваний у наступних оголошеннях записів PL/SQL, і "field_type" - будь-який тип даних. За допомогою атрибута %TYPE можна встановити "type_name" від-повідному типу даних будь-якої змінної (variable) або стовпця (table.column). Атрибут %ROWTYPE дозволяє визначити поле як запис, що відповідає опису стовпців будь-якої базової таблиці.
При оголошенні типу запису можна привласнити її полям деякі значення. Якщо ж для поля вводиться обмеження NOT NULL (для запобігання призначення порожніх значень), то цьому полю треба обов'язково привласнити значення. Наприклад:
TYPE StudRecTyp IS RECORD (nomer NUMBER(5) NOT NULL := 10001,
familiia CHAR(20), priznak CHAR(6), grupa NUMBER(3) := 350);
Оголошення створюваного запису (наприклад, name_plsql_record) виробляється в розділі DECLARE і має вигляд:
name_plsql_record type_name;
Посилання на окремі поля запису здійснюються так:
name_plsql_record.field_name;
Для присвоєння значення конкретному полю запису використовується синтаксис:
name_plsql_record.field_name := expr;
Приклади використання записів у програмах PL/SQL наведені нижче.
2. У наведених прикладах і описах перевірити свої знання у використанні змінних, констант і запису виражень.
20.Змінні, константи й вирази
Упрограмах PL/SQL можуть використовуватися змінні й константи, описувані в розділі DECLARE за допомогою конструкції вигляду:
variable_name [CONSTANT] type_name [NOT NULL] [ { := | DEFAULT }
expr ]
Наприклад:
rojdenie |
DATE; |
|
kol_grup |
SMALLINT := 0; |
|
priznak |
VARCHAR2(6) NOT NULL := 'академ'; |
|
pi |
CONSTANT REAL := 3.14159; |
|
area |
|
REAL := pi * radius**2; |
valid_id |
BOOLEAN; |
|
valid_id |
VARCHAR2(5); |
|
|
|
-- неприпустимий повторний опис valid_id |
i, j, k |
SMALLINT; -- не можна описувати список; треба: |
|
|
|
-- i SMALLINT; j SMALLINT; k SMALLINT; |
credit |
|
REAL(7,2); |
debit |
credit%TYPE; -- тип даних аналогічний типу даних "credit" |
21. Команди керування ходом виконання програми
Команди умовного переходу (IF ...) наведені в табл. 1.1.
Таблиця 1.1
|
Команди умовного переходу (IF )... |
|
|
|
|
IF-THEN |
|
IF умова THEN |
|
|
послідовність команд; |
|
|
END IF; |
|
|
|