Поможем написать учебную работу
Если у вас возникли сложности с курсовой, контрольной, дипломной, рефератом, отчетом по практике, научно-исследовательской и любой другой работой - мы готовы помочь.
Если у вас возникли сложности с курсовой, контрольной, дипломной, рефератом, отчетом по практике, научно-исследовательской и любой другой работой - мы готовы помочь.
PAGE 4
10 Курсори
Курсор мовою SQL являє собою вказівник на підсумковий набір даних, виданих командою SELECT. Курсор виконується тільки в транзакційному блоці. Його використання надає такі переваги:
Оголошення курсора відбувається тільки в складі транзакційного блока, який починається з команди BEGIN. В SQL команда оголошення курсора одночасно виконує його відкриття, вона має такий вигляд:
DECLARE курсор [ BINARY ] [ INSENSITIVE ] [ SCROLL ]
CURSOR FOR запит
[ FOR { READ ONLY | UPDATE [ OF імя_таблиці]}]
Тут:
курсор імя нового курсора;
BINARY означає, що вихідні дані повинні повертатися в двійковому форматі замість стандартного ASCII-коду;
INSENSITIVE забезпечує незалежність даних, повернених курсором, від інших курсорів або підключень, тобто дані, отримані з використанням курсора, не можуть бути зміненими іншими процесам, наприклад, іншими курсорами;
SCROLL забезпечує прокрутку даних, тобто дозволяє багаторазове читання записів;
CURSOR FOR запит запит, підсумковий набір якого стає доступним через курсор;
READ ONLY дозволяє використовувати курсор тільки для читання даних, цей режим установлений за замовчуванням;
UPDATE курсор використовується для редагування таблиць;
OF імя_таблиці імя_таблиці, яка може оновлюватися під час використання курсора.
У поданому нижче прикладі створено транзакцію командою BEGIN і відкрито курсор gazprovid, який буде містити всі записи і всі поля таблиці gazpr:
BEGIN;
DECLARE gazprovid CURSOR FOR SELECT * FROM gazpr;
Вибірка записів із курсора забезпечується командою FETCH, яка має такий вигляд:
FETCH [FORWARD | BACKWARD | RELATIVE] [число | ALL | NEXT | PRIOR]
{IN | FROM} курсор
У цьому оголошенні курсор імя курсора, з якого відбувається вибірка записів. Курсор завжди встановлений на поточну позицію підсумкового набору. Напрям вибірки визначається ключовими словами FORWARD і BACKWARD, за замовчуванням використовується пряма вибірка (FORWARD). Слово RELATIVE число означає зміщення на задану кількість записів відносно поточної позиції курсора. У команді замість RELATIVE може використовуватися ключове слово ABSOLUTE абсолютне позиціонування, тобто переміщення до заданого запису.
За ключовим словом, який ідентифікує напрям, можна вказувати кількість записів. Допускається вказання конкретного числа записів (у вигляді цілочислової константи) або одного з декількох ключових слів, з яких:
ALL означає, що команда повертає всі записи, починаючи з поточної позиції,
NEXT (використовується за замовчуванням) наступний запис від поточної позиції,
PRIOR запис, який знаходиться перед поточним.
Ключові слова IN і FROM еквівалентні, з них команда повинна мати якесь одне.
Нижче у прикладі з метою перевірки роботи курсора спочатку виводяться записи таблиці gazpr командою SELECT. Потім вибираються три записи підсумкового набору, на який посилається курсор gazprovid. Далі команда FETCH з ключовим словом NEXT вибирає чевертий запис, після чого вона з ключовим словом PRIOR знову повертається до третього запису.
SELECT * FROM gazpr;
Розділ Messages: Total query runtime: 31 ms. 5 rows retrieved.
Розділ Data Output:
1;"Україна ";8;1400
3;"Уренгой-Помари-Ужгород ";6;1800
4;"Гадяч-Париж ";7;1500
5;"Гадяч-держкордон ";2;800
2;"Єлецьк-Орел ";8;123
BEGIN;
DECLARE gazprovid CURSOR FOR SELECT * FROM gazpr;
Розділ Messages: Query returned successfully with no result in 15 ms.
FETCH FORWARD 3 FROM gazprovid;
Розділ Data Output:
1;"Україна ";8;1400
3;"Уренгой-Помари-Ужгород ";6;1800
4;"Гадяч-Париж ";7;1500
FETCH NEXT FROM gazprovid;
Розділ Data Output:
5;"Гадяч-держкордон ";2;800
FETCH PRIOR FROM gazprovid;
Розділ Data Output:
4;"Гадяч-Париж ";7;1500
Число записів може бути як додатнім, так і відємним. При додатньому значенні відлік ведеться в напрямку, заданому відповідним параметром (якщо параметр не вказаний, за замовчуванням використовується параметр FORWARD).
При відємній кількості записів відлік ведеться в напрямку, протележному заданому. Наприклад, конструкція FORWARD -5 еквівалентна конструкції BACKWARD 5. Якщо кількість запрошених записів перевищує кількість записів у базі, команда FETCH вибирає всі існуючі записи у вказаному напрямку.
У подальшому прикладі виготовляється курсор gazprovid, який повертає дані з таблиці gazpr. Наступна команда вибирає перші два його записи:
BEGIN;
FETCH FORWARD 2 IN gazprovid;
У нижченаведеному прикладі конструкція BACKWARD -2 також вибирає два записи в прямому напрямку:
FETCH BACKWARD - 2 IN gazprovid;
А ця команда демонструє вибірку в зворотному напрямку через курсор gazprovid:
FETCH BACKWARD 3 IN gazprovid;
FETCH PRIOR IN gazprovid; -- на 1 назад
FETCH NEXT IN gazprovid; -- на 1 вперед
FETCH 2 IN gazprovid; -- те ж, що NEXT 2
Спроба вибірки нуля записів ключовим словом RELATIVE видає поточний запис, у деяких ранніх версіях SQL спричиняє помилку
ERROR: FETCH/RELATIVE at current positionis not supported.
Це повязано з тим, що відповідно до стандарту SQL92 команда FETCH RELATIVE FROM курсор повинна забезпечувати повторну вибірку запису в поточній позиції курсора. У деяких версіях PostgreSQL цей синтаксис не підтримується. Без ключового слова RELATIVE число 0 інтерпретується як запит на вибірку всіх записів. Але з ключовим словом RELATIVE PostgreSQL припускає, що використовується синтаксис SQL92, і замість того, щоб повернути всі записи, виводить повідомлення про помилку.
Переміщення курсора до заданого запису виконується командою MOVE:
MOVE [FORWARD | BACKWARD | RELATIVE] [число |ALL | NEXT | PRIOR] {IN | FROM} курсор
Як видно з цього оголошення, синтаксис команди MOVE дуже близький до синтаксису команди FETCH. Втім, команда MOVE ніяких записів не повертає і лише переміщає поточну позицію курсора. Зміщення задається цілочисловою константою або ключовими словами ALL (переміщення в заданому напрямку на максимально можливу відстань), NEXT або PRIOR. Нижче у прикладі поточна позиція курсора переміщується на 3 записи вперед:
MOVE RELATIVE 3 FROM gazprovid;
Наведемо приклад переміщення поточної позиції курсора:
MOVE FORWARD 3 IN gazprovid;
Закриття курсора забезпечується командою CLOSE. Курсор також автоматично закривається при виході з транзакційного блоку, в якому він знаходиться, при фіксації транзакції командою COMMIT або при її відкоті командою ROLLBACK.
Команда CLOSE має такий вигляд (курсор імя курсора, який закривається):
CLOSE курсор
Команда CLOSE закриває відкритий курсор і звільняє всі використовувані ним ресурси. Коли потреба в курсорі відпадає, його слід закривати. Після закриття курсора подальші операції з ним стають неможливими.
У нижченаведеному прикладі курсор gazoprovid закривається і звільняє займану ним память:
CLOSE gazprovid;
Якщо спробуємо прочитати курсор gazprovid після його закриття командою:
FETCH NEXT FROM gazprovid;
то в розділі Messages одержимо повідомлення про помилку, оскільки дані курсора стають недоступними:
ERROR: cursor "gazprovid" does not exist