
PL/SQL блок включает три ключевых сегмента: DECLARE – для объявления переменных, констант, курсоров и пользовательских типов; BEGIN – для выполнения команд; EXCEPTION – для обработки ошибок. Структура блока позволяет объединять SQL и управляющие конструкции в едином модуле.
В разделе BEGIN применяются DML-команды: INSERT, UPDATE, DELETE, MERGE и SELECT INTO. Для управления потоком используются конструкции IF…THEN, CASE, LOOP, FOR, WHILE. Допустим вызов процедур и функций как встроенных, так и пользовательских.
В блоке EXCEPTION реализуется перехват ошибок. Наиболее востребованные команды – WHEN OTHERS THEN для обработки всех исключений, RAISE для проброса ошибок, SQLCODE и SQLERRM для получения кода и описания ошибки. Это обеспечивает точный контроль исполнения и отладку кода.
Рекомендуется структурировать PL/SQL блоки, разделяя крупные задачи на отдельные процедуры или функции. Это упрощает поддержку кода, повышает читаемость и уменьшает вероятность ошибок при масштабировании решений.
Какие команды можно использовать в PL/SQL блоке
PL/SQL блок состоит из трёх частей: декларативной, исполняемой и секции обработки исключений. В декларативной части используются команды для объявления переменных, констант, типов, курсоров и исключений. Например: DECLARE v_count NUMBER; или CURSOR cur IS SELECT id FROM employees;.
В исполняемой части применяются операторы управления потоком: SELECT INTO, INSERT, UPDATE, DELETE, MERGE, FOR, WHILE, LOOP, EXIT, GOTO, IF…THEN…ELSE, CASE. Эти команды позволяют управлять логикой выполнения и изменять данные в базе.
Команда SELECT INTO используется для извлечения данных из таблиц в переменные: SELECT salary INTO v_salary FROM employees WHERE id = 100;. Команды DML (INSERT, UPDATE, DELETE, MERGE) применяются для изменения содержимого таблиц внутри блока.
Операторы управления потоком позволяют реализовать циклы и ветвления. Циклы FOR, WHILE и LOOP выполняются до достижения заданных условий. Команды EXIT и GOTO управляют выходом из цикла или переходом к метке. IF…THEN…ELSE и CASE обеспечивают условное выполнение блоков кода.
Секция обработки исключений содержит команды EXCEPTION WHEN для перехвата ошибок: например, WHEN NO_DATA_FOUND THEN или WHEN OTHERS THEN. Внутри неё можно использовать команды журналирования или вызова процедур для обработки ошибок.
Дополнительно в PL/SQL блоках применяются вызовы процедур и функций, управляющие команды COMMIT, ROLLBACK, SAVEPOINT для контроля транзакций.
Объявление переменных и констант в PL/SQL блоке
В PL/SQL объявление переменных и констант происходит в разделе DECLARE блока. Переменные служат для хранения данных в процессе выполнения блока, константы – для значений, которые не изменяются.
Синтаксис объявления переменной:
имя_переменной [CONSTANT] тип_данных [NOT NULL] [:= значение_по_умолчанию];
Примеры:
| Пример | Описание |
|---|---|
v_count NUMBER := 0; |
Переменная v_count типа NUMBER с начальным значением 0. |
v_name VARCHAR2(50); |
Переменная v_name типа VARCHAR2 длиной до 50 символов, без начального значения. |
c_rate CONSTANT NUMBER := 3.14; |
Константа c_rate типа NUMBER с фиксированным значением 3.14. |
v_date DATE := SYSDATE; |
Переменная v_date типа DATE, инициализированная текущей датой. |
Рекомендации по объявлению:
- Использовать явное указание типа данных для повышения читаемости и предотвращения ошибок.
- Для констант применять ключевое слово
CONSTANTи задавать начальное значение. - Использовать префиксы в именах (
v_для переменных,c_для констант) для упрощения поддержки кода. - При необходимости использовать
%TYPEили%ROWTYPEдля автоматического присвоения типа данных.
Пример использования %TYPE:
v_salary employees.salary%TYPE;
Этот подход гарантирует, что переменная v_salary будет иметь тот же тип данных, что и столбец salary таблицы employees, исключая ошибки при изменении структуры таблицы.
Использование операторов присваивания и вычислений
В PL/SQL оператор присваивания представлен символом :=. Он используется для передачи значения переменной или константе внутри блока. Например: total := price * quantity; – присваивает переменной total результат умножения.
Операторы вычислений включают арифметические: +, -, *, /, MOD. Они применяются внутри выражений и могут комбинироваться. Пример: discount := (price * rate) / 100;.
Для сложных вычислений рекомендуется использовать скобки для явного указания порядка операций, так как PL/SQL следует стандартным правилам приоритета: сначала скобки, затем умножение и деление, потом сложение и вычитание.
Для присваивания значений также применяют встроенные функции: ROUND, TRUNC, ABS. Например: rounded_value := ROUND(salary, 2); округляет значение до двух знаков после запятой.
Присваивание в PL/SQL не ограничено простыми выражениями. Можно использовать подзапросы: max_salary := (SELECT MAX(salary) FROM employees);, что позволяет интегрировать вычисления с данными из базы.
Для повышения читаемости кода рекомендуется разделять сложные вычисления на несколько операторов присваивания и избегать чрезмерно длинных выражений внутри одного оператора.
Управление потоком выполнения: IF, CASE, LOOP
В PL/SQL управление потоком выполнения осуществляется с помощью условных и циклических конструкций. Это позволяет реализовать логическую обработку данных внутри блока кода.
IF – используется для ветвления логики. Формат:
IF условие THEN
инструкции;
ELSIF условие THEN
инструкции;
ELSE
инструкции;
END IF;
IF применяется при необходимости выбора одного из нескольких вариантов действий. Условия проверяются последовательно, выполнение переходит к первому, которое истинно.
CASE – альтернатива множественным IF. Существует два вида: простой и поисковый CASE.
Простой CASE:
CASE выражение
WHEN значение1 THEN инструкции;
WHEN значение2 THEN инструкции;
ELSE инструкции;
END CASE;
Поисковый CASE позволяет использовать логические выражения вместо фиксированных значений:
CASE
WHEN условие1 THEN инструкции;
WHEN условие2 THEN инструкции;
ELSE инструкции;
END CASE;
CASE удобен для улучшения читаемости и уменьшения количества вложенных IF.
LOOP – базовая конструкция цикла. Существует несколько разновидностей: простой LOOP, WHILE LOOP и FOR LOOP.
Простой LOOP:
LOOP
инструкции;
EXIT WHEN условие;
END LOOP;
WHILE LOOP выполняется при истинности условия:
WHILE условие LOOP
инструкции;
END LOOP;
FOR LOOP используется при известном диапазоне итераций:
FOR переменная IN [REVERSE] начальное_значение..конечное_значение LOOP
инструкции;
END LOOP;
Рекомендация: использовать FOR LOOP для фиксированных диапазонов, WHILE LOOP – когда количество итераций заранее неизвестно, а простой LOOP – при необходимости гибкого контроля выхода из цикла.
Работа с курсорами и FETCH в PL/SQL
Курсоры в PL/SQL используются для управления результатами SQL-запросов. Они позволяют последовательно обрабатывать набор строк, возвращаемых запросом.
Типы курсоров
- Явные курсоры – создаются вручную для обработки результатов конкретного запроса.
- Неявные курсоры – автоматически создаются PL/SQL для операций DML (INSERT, UPDATE, DELETE, SELECT INTO).
Создание и использование явного курсора
- Объявление курсора:
CURSOR имя_курсора IS SELECT столбец1, столбец2 FROM таблица WHERE условие;
- Открытие курсора:
OPEN имя_курсора;
- Извлечение данных с помощью FETCH:
FETCH имя_курсора INTO переменная1, переменная2;
- Закрытие курсора:
CLOSE имя_курсора;
Особенности FETCH
- FETCH извлекает одну строку за раз из набора результатов.
- Можно использовать FETCH в цикле
LOOPдля обработки всех строк:LOOP FETCH имя_курсора INTO переменная1, переменная2; EXIT WHEN имя_курсора%NOTFOUND; -- обработка данных END LOOP;
- После FETCH можно проверять атрибуты курсора:
%FOUND– возвращает TRUE, если строка была извлечена.%NOTFOUND– TRUE, если строк больше нет.%ROWCOUNT– количество извлечённых строк.
Рекомендации при работе с курсорами
- Закрывайте курсоры после использования, чтобы избежать утечек памяти.
- Для выборок большого объёма используйте BULK COLLECT для повышения производительности.
- При сложных запросах предпочитайте явные курсоры для управления логикой обработки.
- Используйте параметризованные курсоры для повышения гибкости и переиспользуемости кода.
Вызов встроенных и пользовательских процедур и функций
В PL/SQL вызов процедур и функций осуществляется внутри блока BEGIN…END, DECLARE или в другом PL/SQL блоке. Встроенные процедуры и функции доступны напрямую без дополнительного объявления, пользовательские требуют предварительного создания с помощью CREATE PROCEDURE или CREATE FUNCTION.
Пример вызова встроенной процедуры:
SET SERVEROUTPUT ON;
Для вызова пользовательской процедуры используется следующий синтаксис:
имя_процедуры(параметры);. Параметры могут быть позиционными или именованными. Например:
BEGIN my_procedure(param1 => 100, param2 => 'Тест'); END;.
Функции вызываются аналогично, но возвращают значение, которое можно присвоить переменной или использовать в выражении. Пример:
DECLARE result NUMBER; BEGIN result := my_function(50); END;.
Рекомендуется для упрощения поддержки использовать именованные параметры, особенно если процедура или функция содержит более двух аргументов. Это повышает читаемость и снижает риск ошибок при изменении порядка параметров.
При использовании процедур и функций важно учитывать область видимости: процедуры, созданные в пакете, должны вызываться через имя пакета:
package_name.procedure_name(...);.
Для отладки полезно применять встроенные функции, например DBMS_UTILITY.FORMAT_ERROR_BACKTRACE, чтобы определить строку, где возникла ошибка при выполнении процедуры или функции.
При частом вызове процедур или функций, особенно в циклах, рекомендуется учитывать влияние на производительность и избегать избыточных обращений к базе данных внутри этих вызовов.
Обработка исключений с EXCEPTION

В PL/SQL блоках раздел EXCEPTION используется для перехвата и обработки ошибок во время выполнения кода. Он размещается в конце блока после секции BEGIN ... END и начинается ключевым словом EXCEPTION.
Синтаксис обработки исключений:
EXCEPTION
WHEN exception_name THEN
-- действия при возникновении исключения
В PL/SQL существуют три категории исключений:
- Предопределённые – стандартные ошибки Oracle, например
NO_DATA_FOUND,TOO_MANY_ROWS,ZERO_DIVIDE. - Пользовательские – объявляются с помощью
EXCEPTIONи обрабатываются вручную. - Необработанные системные – ошибки, не имеющие явной обработки, приводящие к завершению выполнения блока.
Пример обработки предопределённого исключения:
BEGIN
SELECT salary INTO v_salary FROM employees WHERE employee_id = 9999;
EXCEPTION
WHEN NO_DATA_FOUND THEN
DBMS_OUTPUT.PUT_LINE('Сотрудник не найден');
END;
Для пользовательских исключений необходимо объявить их перед блоком BEGIN:
DECLARE
e_custom EXCEPTION;
BEGIN
IF condition THEN
RAISE e_custom;
END IF;
EXCEPTION
WHEN e_custom THEN
DBMS_OUTPUT.PUT_LINE('Произошло пользовательское исключение');
END;
Использование конструкции OTHERS позволяет обработать все непредусмотренные ошибки:
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('Ошибка: ' || SQLERRM);
Рекомендации:
- Обрабатывать только необходимые исключения, чтобы избежать скрытия критических ошибок.
- Использовать
SQLCODEиSQLERRMдля получения кода и текста ошибки. - Для сложных блоков создавать отдельные процедуры обработки исключений для улучшения читаемости и поддержки.
Встроенные SQL-команды внутри PL/SQL

PL/SQL поддерживает выполнение встроенных SQL-команд напрямую внутри блоков кода. Эти команды делятся на DML (Data Manipulation Language), DDL (Data Definition Language) и управляющие запросы SELECT.
Основные виды встроенных SQL-команд:
- DML: INSERT, UPDATE, DELETE, MERGE – применяются для изменения данных в таблицах.
- DDL: CREATE, ALTER, DROP, TRUNCATE – выполняют изменение структуры базы данных. Для их использования требуется динамический SQL через EXECUTE IMMEDIATE.
- SELECT INTO: извлекает данные в переменные PL/SQL.
Пример DML внутри PL/SQL:
BEGIN
UPDATE employees
SET salary = salary * 1.1
WHERE department_id = 10;
COMMIT;
END;
Рекомендации при использовании встроенных SQL:
- Использовать SELECT INTO только при гарантии наличия одной строки результата, иначе будет исключение NO_DATA_FOUND или TOO_MANY_ROWS.
- Для выполнения DDL применять EXECUTE IMMEDIATE, так как DDL не поддерживается напрямую в PL/SQL блоках.
- Всегда контролировать транзакции: COMMIT и ROLLBACK должны использоваться осознанно.
- При массовом обновлении данных применять BULK COLLECT и FORALL для повышения производительности.
- Использовать явные курсоры для сложных SELECT-запросов с обработкой множества строк.
Пример динамического DDL:
BEGIN
EXECUTE IMMEDIATE 'CREATE TABLE temp_table (id NUMBER, name VARCHAR2(50))';
END;
Встроенные SQL-команды в PL/SQL позволяют эффективно взаимодействовать с базой данных при условии правильной организации транзакций и обработки ошибок.
Использование BULK COLLECT и FORALL для массовых операций

BULK COLLECT применяется для одновременной загрузки нескольких строк из базы данных в коллекции PL/SQL, что значительно сокращает количество контекстных переключений между SQL и PL/SQL. Формат запроса:
SELECT … BULK COLLECT INTO collection FROM …;
Рекомендуется использовать при извлечении более 100–200 строк, чтобы минимизировать накладные расходы. Оптимально сочетать с ограничением LIMIT для обработки данных пакетами и предотвращения переполнения памяти.
Пример:
DECLARE
TYPE t_emp IS TABLE OF employees%ROWTYPE;
l_emp t_emp;
BEGIN
SELECT * BULK COLLECT INTO l_emp
FROM employees
WHERE department_id = 10
LIMIT 500;
END;
FORALL используется для выполнения DML-операций над множеством записей коллекции в одном контекстном переключении. Синтаксис:
FORALL i IN collection.FIRST..collection.LAST
При работе с FORALL критически важно исключить ошибки по каждой записи через SAVE EXCEPTIONS и использовать индексацию коллекций.
Пример:
DECLARE
TYPE t_salary IS TABLE OF employees.salary%TYPE;
l_salary t_salary := t_salary();
BEGIN
-- Заполнение коллекции
SELECT salary BULK COLLECT INTO l_salary
FROM employees
WHERE department_id = 20;
-- Массовое обновление
FORALL i IN l_salary.FIRST..l_salary.LAST
UPDATE employees
SET salary = l_salary(i) * 1.05
WHERE employee_id = i;
END;
Рекомендации:
- Использовать BULK COLLECT и FORALL совместно для оптимизации массовых операций.
- Ограничивать размер пакета через LIMIT при загрузке больших данных.
- Применять SAVE EXCEPTIONS для отладки и обработки ошибок.
- Следить за использованием памяти, особенно при работе с большими коллекциями.
Вопрос-ответ:
Какие типы команд можно использовать внутри блока PL/SQL?
Внутри блока PL/SQL можно применять три основные группы команд: декларативные, исполнительные и обработчики исключений. В декларативной части описываются переменные, константы, типы данных и курсоры. Исполнительная часть содержит команды обработки данных, например SELECT INTO, INSERT, UPDATE, DELETE, вызовы процедур и функций. Часть обработки исключений предназначена для перехвата и обработки ошибок, возникающих во время выполнения блока.
Можно ли в PL/SQL блоке выполнять несколько SQL-запросов подряд?
Да, внутри PL/SQL блока можно выполнять несколько SQL-запросов подряд, разделяя их точкой с запятой. Например, можно сначала выполнить INSERT для добавления данных, затем UPDATE для изменения, и SELECT INTO для получения результатов. Все команды выполняются последовательно, и при ошибке выполнение блока может быть остановлено, если ошибка не перехвачена в части обработки исключений.
Как в PL/SQL блоке использовать условные конструкции?
В PL/SQL поддерживаются условные конструкции IF…THEN…ELSE и CASE. Они позволяют изменять ход выполнения блока в зависимости от значений переменных или результатов запросов. Например, с помощью IF можно проверить значение переменной и выполнить соответствующие SQL-команды или присвоения. CASE используется для более компактной записи нескольких вариантов условий внутри выражений или операторов.
Что такое курсоры в PL/SQL и как их применять в блоках?
Курсоры в PL/SQL позволяют работать с результатами SELECT-запросов по одной строке или набору строк. Они бывают явные и неявные. Явный курсор создаётся и открывается вручную, после чего строки извлекаются в переменные. Неявный курсор формируется автоматически для каждого SQL-запроса внутри блока. Курсоры полезны при необходимости обрабатывать результаты сложных запросов построчно.
Как обрабатывать ошибки внутри PL/SQL блока?
В PL/SQL блоке предусмотрена часть обработки исключений — секция EXCEPTION. Она позволяет перехватывать ошибки, возникающие при выполнении блока, и выполнять альтернативные действия. Например, можно отлавливать стандартные ошибки ORA-XXXX или создавать собственные исключения. В обработчиках можно выводить сообщения, фиксировать ошибки в журнал или корректировать данные, чтобы избежать аварийного завершения выполнения.
Какие типы команд можно использовать внутри PL/SQL блока?
Внутри PL/SQL блока допустимо применять несколько категорий команд. Основные из них — это декларативная часть, исполняемая часть и часть обработки исключений. В декларативной части определяются переменные, константы, курсоры, типы данных и другие элементы. В исполняемой части размещаются операторы, которые выполняют логику программы — например, операторы присваивания, условные конструкции (IF…THEN…ELSE), циклы (FOR, WHILE, LOOP), вызовы процедур и функций. Часть обработки исключений используется для отлавливания и обработки ошибок, которые могут возникнуть во время выполнения блока. Кроме того, в PL/SQL блоках допустимо использовать SQL-команды SELECT, INSERT, UPDATE, DELETE и DDL-команды через EXECUTE IMMEDIATE.
