JavaRush /Курсы /SQL SELF /Анализ типичных ошибок при работе с управляющими конструк...

Анализ типичных ошибок при работе с управляющими конструкциями и логированием

SQL SELF
52 уровень , 4 лекция
Открыта

Переходя к основной теме, давайте остановимся на наиболее распространенных ошибках и недочетах, с которыми вы можете столкнуться. Ведь ошибки в SQL — это боль любого разработчика, и, как правило, они происходят в самый неподходящий момент.

1. Ошибки синтаксиса: "забыл закрыть IF"

Ошибки синтаксиса — это самые базовые проблемы, но они встречаются чаще, чем вы думаете. Например, если вы забыли закрыть условный блок IF с помощью END IF;, компилятор сразу вас осудит.

Пример ошибки:

CREATE OR REPLACE FUNCTION check_number(num INTEGER)
RETURNS TEXT AS $$
BEGIN
    IF num > 0 THEN
        RETURN 'Positive';
    ELSE
        RETURN 'Negative';
-- где-то потерялось END IF;
END;
$$ LANGUAGE plpgsql;

При попытке выполнить этот код вы получите ошибку: ERROR: syntax error at or near "END". Почему? Потому что блок IF остался открытым.

Как избежать подобных ошибок?

Всегда используйте четкую структуру кода. Когда вы открываете блок (например, IF), сразу пишите его закрытие. Вот исправленный пример:

CREATE OR REPLACE FUNCTION check_number(num INTEGER)
RETURNS TEXT AS $$
BEGIN
    IF num > 0 THEN
        RETURN 'Positive';
    ELSE
        RETURN 'Negative';
    END IF; -- не забудьте закрыть блок
END;
$$ LANGUAGE plpgsql;

2. Забытая обработка всех условий в CASE: "А что, если я никуда не попаду?"

Когда вы используете CASE, всегда задавайте ветку ELSE для обработки неожиданного поведения. Отсутствие этой ветки может привести к нежелательному возврату NULL.

Пример ошибки:

CREATE OR REPLACE FUNCTION grade_result(grade CHAR)
RETURNS TEXT AS $$
BEGIN
    RETURN CASE grade
        WHEN 'A' THEN 'Excellent'
        WHEN 'B' THEN 'Good'
        WHEN 'C' THEN 'Average'
        -- А что, если grade = 'D' или другая оценка?
    END;
END;
$$ LANGUAGE plpgsql;

Если вы передадите значение D, функция вернет NULL, что может вызвать проблемы в вашем коде.

Исправленный вариант:

CREATE OR REPLACE FUNCTION grade_result(grade CHAR)
RETURNS TEXT AS $$
BEGIN
    RETURN CASE grade
        WHEN 'A' THEN 'Excellent'
        WHEN 'B' THEN 'Good'
        WHEN 'C' THEN 'Average'
        ELSE 'Unknown grade' -- Перехватываем все остальные случаи
    END;
END;
$$ LANGUAGE plpgsql;

3. Проблемы с бесконечными циклами: "Почему сервер завис?"

Используя цикл LOOP, легко забыть добавить условие для выхода из цикла. Это может привести к бесконечному выполнению:

Пример ошибки:

CREATE OR REPLACE FUNCTION infinite_loop_demo()
RETURNS VOID AS $$
DECLARE
    i INTEGER := 1;
BEGIN
    LOOP
        i := i + 1;
        -- Нет условия для выхода!
    END LOOP;
END;
$$ LANGUAGE plpgsql;

Этот код приведет к зависанию сервера, потому что цикл никогда не завершится.

Как исправить:

Добавьте условие выхода с помощью EXIT:

CREATE OR REPLACE FUNCTION finite_loop_demo()
RETURNS VOID AS $$
DECLARE
    i INTEGER := 1;
BEGIN
    LOOP
        i := i + 1;
        IF i > 10 THEN
            EXIT; -- Условие выхода
        END IF;
    END LOOP;
END;
$$ LANGUAGE plpgsql;

4. Пропуск итераций в циклах: "А что с недостающими данными?"

При использовании CONTINUE для пропуска итераций может возникнуть ошибка, если вы не учли все варианты поведения. Например:

Пример ошибки:

CREATE OR REPLACE FUNCTION skip_even()
RETURNS VOID AS $$
DECLARE
    i INTEGER := 0;
BEGIN
    WHILE i < 10 LOOP
        i := i + 1;
        IF i % 2 = 0 THEN
            CONTINUE; -- Чисто пропускаем чётные значения
        END IF;
        RAISE NOTICE 'Odd number: %', i;
    END LOOP;
END;
$$ LANGUAGE plpgsql;

Что, если все числа будут четными? Сервер будет работать, но результата вы не увидите.

Как исправить:

Убедитесь, что вы обрабатываете все данные корректно, и добавляйте логи для контроля:

CREATE OR REPLACE FUNCTION skip_even_logging()
RETURNS VOID AS $$
DECLARE
    i INTEGER := 0;
BEGIN
    WHILE i < 10 LOOP
        i := i + 1;
        IF i % 2 = 0 THEN
            RAISE NOTICE 'Skipping even number: %', i;
            CONTINUE;
        END IF;
        RAISE NOTICE 'Odd number: %', i;
    END LOOP;
END;
$$ LANGUAGE plpgsql;

Теперь вы видите, какие числа были пропущены.

5. Неправильная обработка ошибок: "Где мой RAISE EXCEPTION?"

Обработка ошибок через RAISE EXCEPTION — мощный инструмент, но он может быть легко испорчен неправильным использованием.

Пример ошибки:

CREATE OR REPLACE FUNCTION calculate_square(num INTEGER)
RETURNS INTEGER AS $$
BEGIN
    IF num < 0 THEN
        RAISE 'Negative number is not allowed!';
    END IF;
    RETURN num * num;
END;
$$ LANGUAGE plpgsql;

Этот код вызовет ошибку, так как синтаксис RAISE неверен (отсутствует уровень сообщения).

Исправленный вариант:

CREATE OR REPLACE FUNCTION calculate_square(num INTEGER)
RETURNS INTEGER AS $$
BEGIN
    IF num < 0 THEN
        RAISE EXCEPTION 'Negative number is not allowed!';
    END IF;
    RETURN num * num;
END;
$$ LANGUAGE plpgsql;

6. Ошибки при логировании: "Почему мои ошибки не пишутся в error_log?"

Некорректная запись в таблицу error_log может произойти из-за ошибок в запросах INSERT INTO.

Пример ошибки:

CREATE OR REPLACE FUNCTION log_error(err_msg TEXT)
RETURNS VOID AS $$
BEGIN
    INSERT INTO error_log (error_message, error_time)
    VALUES (err_msg, CURRENT_TIMESTAMP); -- А если ошибка в столбцах?
END;
$$ LANGUAGE plpgsql;

Если в таблице error_log было изменено имя столбца (например, на error_msg), это вызовет ошибку.

Как избежать:

Всегда проверяйте структуру таблицы или используйте строгую схему для управления данными.

7. Общая невнимательность и "человеческий фактор"

Ошибки бывают не только техническими, но и связанными с невнимательностью. Забытая отладка, неиспользуемые переменные или отсутствие форматирования кода могут превратить вашу функцию в кашу.

Пример:

DECLARE
    i INTEGER; -- Зачем, если переменная не используется?

Исправление: удаляйте ненужные части кода, чтобы он оставался чистым и понятным.

Теперь вы готовы избежать самых распространенных ошибок в PL/pgSQL и писать код, который приносит больше радости, чем боли. Не забывайте тестировать, логировать и вовремя фиксить баги — этим вы сэкономите себе массу нервов и клиентских звонков!

2
Задача
SQL SELF, 52 уровень, 4 лекция
Недоступна
Обработка всех условий в `CASE`
Обработка всех условий в `CASE`
1
Опрос
Обработка ошибок, 52 уровень, 4 лекция
Недоступен
Обработка ошибок
Обработка ошибок
Комментарии (2)
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ
Анатолий Уровень 53
13 марта 2026
❤️
Ra Уровень 1 Student
20 августа 2025
В опросе: Как идентифицировать все ветки в выражении CASE? - по моему, надо перефразировать, не подходит по смыслу Какой результат вернёт функция, если передать в неё отрицательное число, а условие не обработано? - вообще галлюцинации ИИ