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-запит замість циклу.

Коментарі
ЩОБ ПОДИВИТИСЯ ВСІ КОМЕНТАРІ АБО ЗАЛИШИТИ КОМЕНТАР,
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ