JavaRush /Курсы /SQL SELF /Использование циклов: LOOP, FOR, WHILE в PL/pgSQL

Использование циклов: LOOP, FOR, WHILE в PL/pgSQL

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

Циклы позволяют выполнять блок кода несколько раз подряд, пока выполняется определённое условие или пока выполняется итерация по какому-либо набору данных. Это крайне полезно для автоматизации задач, обработки больших объемов данных или выполнения повторяющихся операций.

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

В PostgreSQL поддерживаются несколько видов циклов:

  1. LOOP — универсальный цикл, который выполняется до тех пор, пока явно не будет остановлен.
  2. FOR — цикл с заданным количеством итераций по диапазону чисел или результату запроса.
  3. WHILE — цикл, который выполняется до тех пор, пока условие истинно.

Давайте разберём каждый вид по отдельности.

Бесконечный цикл:LOOP

LOOP — это базовая форма цикла в PL/pgSQL, которая повторяет выполнение блока кода. Этот цикл работает бесконечно, и его выполнение нужно завершать вручную с помощью команды EXIT.

Синтаксис:

LOOP
    -- Ваш код здесь
END LOOP;

Приведём пример. Посчитаем сумму чисел от 1 до 10 с помощью LOOP:

DO $$
DECLARE
    counter INT := 1;
    sum INT := 0;
BEGIN
    LOOP
        sum := sum + counter; -- добавляем текущее значение счётчика
        counter := counter + 1; -- увеличиваем счётчик

        -- Завершаем цикл, если счётчик больше 10
        IF counter > 10 THEN
            EXIT;
        END IF;
    END LOOP;

    RAISE NOTICE 'Сумма чисел от 1 до 10: %', sum;
END $$;
  1. Переменная counter увеличивается на каждой итерации.
  2. Условие IF counter > 10 THEN EXIT; завершает цикл, когда счётчик превышает 10.
  3. В конце выводится сумма чисел.

Цикл по диапазону или набору данных: FOR

Второй тип цикла, FOR, используется для итерации по:

  1. Диапазону чисел.
  2. Результату SQL-запроса.

Цикл по диапазону чисел

Синтаксис:

FOR variable IN [REVERSE] start..end LOOP
    -- Ваш код здесь
END LOOP;

Выведем числа от 1 до 5:

DO $$
BEGIN
    FOR i IN 1..5 LOOP
        RAISE NOTICE 'Текущее значение: %', i;
    END LOOP;
END $$;

Пример с обратным порядком:

DO $$
BEGIN
    FOR i IN REVERSE 5..1 LOOP
        RAISE NOTICE 'Обратный порядок: %', i;
    END LOOP;
END $$;

Цикл по результату SQL-запроса

Этот вариант полезен для обработки строк таблицы.

Синтаксис:

FOR variable IN QUERY (SELECT ...) LOOP
    -- Ваш код здесь
END LOOP;

Приведём пример итерации по строкам таблицы students:

DO $$
DECLARE
    student_name TEXT;
BEGIN
    FOR student_name IN QUERY (SELECT name FROM students) LOOP
        RAISE NOTICE 'Привет, %!', student_name;
    END LOOP;
END $$;

Условный цикл:WHILE

WHILE выполняется до тех пор, пока заданное условие истинно.

Синтаксис:

WHILE условие LOOP
    -- Ваш код здесь
END LOOP;

Давайте посчитаем сумму чисел от 1 до 10 с помощью WHILE:

DO $$
DECLARE
    counter INT := 1;
    sum INT := 0;
BEGIN
    WHILE counter <= 10 LOOP
        sum := sum + counter;
        counter := counter + 1;
    END LOOP;

    RAISE NOTICE 'Сумма чисел от 1 до 10: %', sum;
END $$;

Примеры из реальной жизни

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

Пример 1: генерация таблицы умножения

DO $$
DECLARE
    i INT;
    j INT;
BEGIN
    FOR i IN 1..5 LOOP
        FOR j IN 1..5 LOOP
            RAISE NOTICE '% x % = %', i, j, i * j;
        END LOOP;
    END LOOP;
END $$;

Пример 2: итерация по результатам запроса. Предположим, у нас есть таблица products с полями id и price. Обновим все цены, увеличив их на 10%.

DO $$
DECLARE
    prod RECORD;
BEGIN
    FOR prod IN QUERY (SELECT id, price FROM products) LOOP
        UPDATE products
        SET price = prod.price * 1.1
        WHERE id = prod.id;
    END LOOP;
END $$;

Типичные ошибки и как их избежать

Зацикливание в LOOP или WHILE. Если забыть добавить условие выхода (EXIT или корректное условие в WHILE), цикл никогда не завершится. Примерно то же, что водить машину без тормозов.

Ошибка при итерации по результату запроса. Если структура результирующих данных не соответствует ожидаемому, можно столкнуться с ошибкой в цикле FOR IN QUERY.

Неоптимальные запросы внутри циклов. Например, выполнение UPDATE в каждой итерации может сильно замедлить выполнение. В таких случаях лучше использовать один SQL-запрос вместо цикла.

2
Задача
SQL SELF, 51 уровень, 1 лекция
Недоступна
Использование `FOR` для итерации по запросу
Использование `FOR` для итерации по запросу
Комментарии
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ