Oracle Курсор PL/SQL: неявний, явний, цикл For із прикладом

⚡ Розумний підсумок

Курсори в Oracle PL/SQL – це вказівники на область контексту, яка містить рядки, повернуті SQL-інструкцією. Існує два типи курсорів: неявні курсори, що створюються автоматично для DML, та явні курсори, що оголошуються та контролюються програмістом.

  • 📍 Область контексту: Курсор вказує на область контексту, яка зберігає SQL-інструкцію та її повернений активний набір.
  • Неявний курсор: Oracle автоматично відкриває неявний курсор для кожного оператора DML та однорядкового оператора SELECT INTO.
  • Явний курсор: Програміст оголошує, відкриває, отримує та закриває явний курсор для повного контролю.
  • 🔎 Атрибути курсора: %FOUND, %NOTFOUND, %ISOPEN та %ROWCOUNT повідомляють про стан останньої операції.
  • 🔁 Курсор циклу FOR: Цикл FOR відкривається, отримує та закриває курсор неявно, не потребуючи ручних дій.
  • 🤖 Допомога AI: Помічники штучного інтелекту, такі як цикли курсорів чернетки GitHub Copilot, позначають незакриті курсори та прапорці.

Oracle Курсор PL/SQL Неявний, явний та цикл FOR

Що таке CURSOR у PL/SQL?

Курсор — це вказівник на контекстну область. Oracle створює контекстну область для обробки SQL виписка, і ця область містить всю інформацію про виписку.

PL / SQL дозволяє програмісту керувати контекстною областю за допомогою курсора. Курсор містить рядки, повернуті оператором SQL, а набір рядків, які містить курсор, називається активним набором. Ці курсори також можна назвати, щоб на них можна було посилатися з іншого місця в коді.

Курсор буває двох типів:

  • Неявний курсор
  • Явний курсор

Неявний курсор

Щоразу, коли будь-який Операція DML відбувається в базі даних, створюється неявний курсор, який містить рядки, що використовуються в цій конкретній операції. Ці курсори не можна іменувати, а отже, ними не можна керувати або звертатися до них з іншого місця в коді. Ми можемо звертатися лише до найновішого курсора через атрибути курсора.

Явний курсор

Програмістам дозволено створювати іменовану область контексту для виконання своїх DML-операцій та отримувати над нею більше контролю. Явний курсор слід визначити в розділі оголошення Блок PL/SQL, і він створюється для оператора SELECT, який потрібно використовувати в коді.

Нижче наведено кроки, пов'язані з роботою з явними курсорами:

  • Оголошення курсора: Оголошення курсора означає просто створення однієї іменованої контекстної області для оператора SELECT, яка визначена в частині оголошення. Назва цієї контекстної області така ж, як і назва курсора.
  • Відкриття курсора: Відкриття курсора дає команду PL/SQL виділити пам'ять для цього курсора. Це готує курсор до вибору записів.
  • Отримання даних з курсора: У цьому процесі виконується оператор SELECT, і отримані рядки зберігаються у виділеній пам'яті. Тепер вони називаються активними наборами. Отримання даних з курсора є дією на рівні запису, що означає, що ми можемо отримувати доступ до даних запис за записом. Кожен оператор fetch отримує один активний набір і містить інформацію про цей конкретний запис. Цей оператор такий самий, як і оператор SELECT, який отримує запис і присвоює його змінній у реченні INTO, але не викидає жодних... Винятки.
  • Закриття курсора: Після того, як усі записи будуть отримані, нам потрібно закрити курсор, щоб звільнити пам'ять, виділену для цієї контекстної області.

синтаксис

DECLARE
CURSOR <cursor_name> IS <SELECT statement>;
<cursor_variable declaration>;
BEGIN
OPEN <cursor_name>;
FETCH <cursor_name> INTO <cursor_variable>;
.
.
CLOSE <cursor_name>;
END;

У наведеному вище синтаксисі частина оголошення містить оголошення курсора та змінну курсора, якій будуть присвоєні отримані дані. Курсор створюється для оператора SELECT, який заданий в оголошенні курсора. У частині виконання оголошений курсор відкривається, отримується та закривається.

Атрибути курсора

Як неявний, так і явний курсор мають певні атрибути, до яких можна отримати доступ. Ці атрибути надають більше інформації про операції з курсором. Нижче наведено різні атрибути курсора та їх використання.

Атрибут курсора Опис
% ЗНАЙДЕНО Повертає логічне значення TRUE, якщо остання операція вибірки успішно вибрала запис; інакше повертає FALSE.
%НЕ ЗНАЙДЕНО Працює протилежно до %FOUND. Повертає значення TRUE, якщо остання операція вибірки не змогла отримати жодного запису.
%ISOPEN Повертає логічне значення TRUE, якщо заданий курсор вже відкритий; інакше повертає FALSE.
%ROWCOUNT Повертає числове значення, що показує фактичну кількість записів, на які вплинула або які було отримано в результаті операції.

Приклад явного курсора: У цьому прикладі ми побачимо, як оголошувати, відкривати, отримувати та закривати явний курсор. Ми проектуватимемо всі імена співробітників з таблиці emp за допомогою курсора. Ми також використовуватимемо атрибут cursor, щоб налаштувати цикл на отримання всіх записів з курсора.

На скріншоті нижче показано цей приклад явного курсора та його вивід у Oracle.

Приклад явного курсора для отримання імен співробітників з таблиці emp у Oracle PL / SQL

DECLARE
CURSOR guru99_det IS SELECT emp_name FROM emp;
lv_emp_name emp.emp_name%type;
BEGIN
OPEN guru99_det;
LOOP
FETCH guru99_det INTO lv_emp_name;
IF guru99_det%NOTFOUND
THEN
EXIT;
END IF;
Dbms_output.put_line('Employee Fetched:'||lv_emp_name);
END LOOP;
Dbms_output.put_line('Total rows fetched is'||guru99_det%ROWCOUNT);
CLOSE guru99_det;
END;
/

Вихід

Employee Fetched:BBB
Employee Fetched:XXX
Employee Fetched:YYY
Total rows fetched is 3

Code Пояснення

  • Code рядок 2: Оголошення курсора guru99_det для оператора 'SELECT emp_name FROM emp'.
  • Code рядок 3: Оголошення змінної lv_emp_name з %тип прив'язаний до emp.emp_name.
  • Code рядок 5: Відкриття курсора guru99_det.
  • Code рядок 6: Встановлення базового оператора циклу для отримання всіх записів у таблиці emp.
  • Code рядок 7: Отримує дані guru99_det та присвоює значення lv_emp_name.
  • Code рядок 8: Використання атрибута курсора %NOTFOUND для перевірки, чи всі записи в курсорі отримано. Якщо отримано, повертається значення TRUE, і керування виходить з циклу; інакше керування продовжує отримання даних з курсора та друкує їх.
  • Code рядок 10: Умова EXIT для оператора циклу.
  • Code рядок 12: Надрукуйте отримане ім'я співробітника.
  • Code рядок 14: Використання атрибута курсора %ROWCOUNT для знаходження загальної кількості записів, отриманих курсором.
  • Code рядок 15: Після виходу з циклу курсор закривається, а виділена пам'ять звільняється.

Оператор курсору циклу FOR

Курсор Цикл FOR можна використовувати для роботи з курсорами. Ми можемо вказати ім'я курсора замість обмеження діапазону в операторі циклу FOR, щоб цикл працював від першого запису курсора до останнього запису курсора. Змінна курсора, відкриття курсора, вибірка та закриття курсора виконуються неявно циклом FOR.

синтаксис

DECLARE
CURSOR <cursor_name> IS <SELECT statement>;
BEGIN
FOR I IN <cursor_name>
LOOP
.
.
END LOOP;
END;

У наведеному вище синтаксисі частина оголошення містить оголошення курсора. Курсор створюється для оператора SELECT, який заданий в оголошенні курсора. У частині виконання оголошений курсор встановлюється в циклі FOR, і змінна циклу 'I' поводиться як змінна курсора в цьому випадку.

Oracle Курсор для прикладу циклу: У цьому прикладі ми проектуємо всі імена співробітників з таблиці emp за допомогою циклу cursor-FOR.

DECLARE
CURSOR guru99_det IS SELECT emp_name FROM emp;
BEGIN
FOR lv_emp_name IN guru99_det
LOOP
Dbms_output.put_line('Employee Fetched:'||lv_emp_name.emp_name);
END LOOP;
END;
/

Вихід

Employee Fetched:BBB
Employee Fetched:XXX
Employee Fetched:YYY

Code Пояснення

  • Code рядок 2: Оголошення курсора guru99_det для оператора 'SELECT emp_name FROM emp'.
  • Code рядок 4: Побудова циклу FOR для курсора з використанням змінної циклу lv_emp_name.
  • Code рядок 6: Друк імені співробітника в кожній ітерації циклу.
  • Code рядок 7: Вихід з циклу (END LOOP).

Примітка: У циклі FOR з використанням курсора атрибути курсора використовувати не можна, оскільки відкриття, вибірка та закриття курсора неявно виконується циклом FOR.

Поширені запитання

ПОСИЛАННЯ-КУРСОР (змінна курсора) – це вказівник на набір результатів запиту. На відміну від статичного курсора, він може відкривати різні запити під час виконання та передавати результати між блоками PL/SQL або клієнтським програмам.

Звичайний курсор отримує один рядок за кожну операцію FETCH, що призводить до багатьох перемикань контексту. ОБ'ЄМНИЙ ЗБІР завантажує багато рядків у колекцію за один раз, що значно скорочує витрати на великі набори результатів.

Так. Оголосіть параметризований курсор, наприклад, CURSOR c(dept NUMBER) IS SELECT …, а потім передайте значення в OPEN c(10). Параметри дозволяють повторно використовувати одне визначення курсора з різними значеннями фільтра.

FOR UPDATE блокує рядки, вибрані курсором, щоб ніхто інший не міг їх змінити. WHERE CURRENT OF потім оновлює або видаляє саме той рядок, який щойно вибрав, без повторення умови WHERE.

Відкриті курсори зберігають свою пам'ять зарезервованою та враховуються в ліміті OPEN_CURSORS. Залишення великої кількості відкритих курсорів зрештою призводить до помилки ORA-01000: перевищено максимальну кількість відкритих курсорів, тому завжди ЗАКРИВАЙТЕ явний курсор після використання.

Кожна команда FETCH перемикається між механізмами PL/SQL та SQL. Тисячі таких перемикачів контексту накопичуються, тому один SQL-запит на основі набору або BULK COLLECT зазвичай обробляє ті самі рядки набагато швидше.

Так. Копілот GitHub створює явні цикли OPEN, FETCH та CLOSE або цикли курсора FOR з коментаря, додає перевірки виходу %NOTFOUND та пропонує назви атрибутів, хоча спочатку слід переглянути логіку.

Помічники штучного інтелекту позначають цикли курсорів по рядках, які можуть перетворитися на SQL на основі наборів або BULK COLLECT, виявляють незакриті курсори та пояснюють поведінку %attribute. Цей огляд машинного навчання покращує продуктивність, перш ніж код потрапить у робочу версію.

Підсумуйте цей пост за допомогою: