Pętle pozwalają wykonać blok kodu kilka razy z rzędu, dopóki spełniony jest określony warunek albo trwa iteracja po jakimś zbiorze danych. To mega przydatne do automatyzacji zadań, obrabiania dużych ilości danych albo wykonywania powtarzalnych operacji.
Wyobraź sobie, że musisz ręcznie rozdać cukierki wszystkim dzieciakom w grupie. Totalny chaos! Zamiast tego możesz przejść przez listę dzieci i każdemu po kolei dać cukierka. W tym scenariuszu "przejście przez listę" — to właśnie pętla.
W PostgreSQL masz kilka rodzajów pętli:
LOOP— uniwersalna pętla, która działa, dopóki nie zatrzymasz jej ręcznie.FOR— pętla z określoną liczbą iteracji po zakresie liczb albo wyniku zapytania.WHILE— pętla, która działa, dopóki warunek jest prawdziwy.
Przejdźmy przez każdy typ osobno.
Pętla nieskończona: LOOP
LOOP — to podstawowa forma pętli w PL/pgSQL, która powtarza wykonanie bloku kodu. Ta pętla działa w nieskończoność i trzeba ją zakończyć ręcznie za pomocą komendy EXIT.
Składnia:
LOOP
-- Twój kod tutaj
END LOOP;
Przykład. Policzmy sumę liczb od 1 do 10 za pomocą LOOP:
DO $$
DECLARE
counter INT := 1;
sum INT := 0;
BEGIN
LOOP
sum := sum + counter; -- dodajemy aktualną wartość licznika
counter := counter + 1; -- zwiększamy licznik
-- Kończymy pętlę, jeśli licznik większy niż 10
IF counter > 10 THEN
EXIT;
END IF;
END LOOP;
RAISE NOTICE 'Suma liczb od 1 do 10: %', sum;
END $$;
- Zmienne
counterzwiększa się przy każdej iteracji. - Warunek
IF counter > 10 THEN EXIT;kończy pętlę, gdy licznik przekroczy 10. - Na końcu wyświetlana jest suma liczb.
Pętla po zakresie lub zbiorze danych: FOR
Drugi typ pętli, FOR, używasz do iteracji po:
- Zakresie liczb.
- Wyniku zapytania SQL.
Pętla po zakresie liczb
Składnia:
FOR variable IN [REVERSE] start..end LOOP
-- Twój kod tutaj
END LOOP;
Wyświetlmy liczby od 1 do 5:
DO $$
BEGIN
FOR i IN 1..5 LOOP
RAISE NOTICE 'Aktualna wartość: %', i;
END LOOP;
END $$;
Przykład z odwrotną kolejnością:
DO $$
BEGIN
FOR i IN REVERSE 5..1 LOOP
RAISE NOTICE 'Odwrotna kolejność: %', i;
END LOOP;
END $$;
Pętla po wyniku zapytania SQL
Ta opcja jest przydatna do przetwarzania wierszy tabeli.
Składnia:
FOR variable IN QUERY (SELECT ...) LOOP
-- Twój kod tutaj
END LOOP;
Przykład iteracji po wierszach tabeli students:
DO $$
DECLARE
student_name TEXT;
BEGIN
FOR student_name IN QUERY (SELECT name FROM students) LOOP
RAISE NOTICE 'Cześć, %!', student_name;
END LOOP;
END $$;
Pętla warunkowa: WHILE
WHILE działa, dopóki podany warunek jest prawdziwy.
Składnia:
WHILE warunek LOOP
-- Twój kod tutaj
END LOOP;
Policzmy sumę liczb od 1 do 10 za pomocą WHILE:
DO $$
DECLARE
counter INT := 1;
sum INT := 0;
BEGIN
WHILE counter <= 10 LOOP
sum := sum + counter;
counter := counter + 1;
END LOOP;
RAISE NOTICE 'Suma liczb od 1 do 10: %', sum;
END $$;
Przykłady z życia codziennego
Teraz, gdy ogarniasz podstawy pętli, zobaczmy przykłady ich użycia.
Przykład 1: generowanie tabliczki mnożenia
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 $$;
Przykład 2: iteracja po wynikach zapytania. Załóżmy, że mamy tabelę products z polami id i price. Zaktualizujemy wszystkie ceny, zwiększając je o 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 $$;
Typowe błędy i jak ich unikać
Zapętlenie w LOOP albo WHILE. Jeśli zapomnisz dodać warunek wyjścia (EXIT albo poprawny warunek w WHILE), pętla nigdy się nie skończy. To trochę jak jazda autem bez hamulców.
Błąd przy iteracji po wyniku zapytania. Jeśli struktura wynikowych danych nie zgadza się z oczekiwaniami, możesz trafić na błąd w pętli FOR IN QUERY.
Nieoptymalne zapytania wewnątrz pętli. Na przykład, wykonywanie UPDATE w każdej iteracji może mocno spowolnić działanie. W takich przypadkach lepiej użyć jednego zapytania SQL zamiast pętli.
GO TO FULL VERSION