CodeGym /Kursy /SQL SELF /Logowanie błędów: poziomy logowania i format wiadomości

Logowanie błędów: poziomy logowania i format wiadomości

SQL SELF
Poziom 55, Lekcja 2
Dostępny

Teraz jesteśmy trochę jak tajni agenci — nasze funkcje i procedury wykonują misje: przetwarzają dane, robią obliczenia albo po prostu czarują coś w bazie. Ale jak się dowiedzieć, jeśli coś pójdzie nie tak? Jak ogarnąć, na którym etapie rozwaliła się "masażowa wanienka dla danych"? Tu z pomocą przychodzą logowanie i obsługa błędów.

Pamiętasz, już zaczynaliśmy ogarniać, jak w PostgreSQL i PL/pgSQL można się "komunikować" i prowadzić logi:

  • RAISE NOTICE: spokojny, kumpelski ton — "Hej, wszystko gra, ale może chcesz na to zerknąć".
  • RAISE WARNING: ton trochę głośniejszy — "Oj, coś tu dziwnego, może sprawdź".
  • RAISE EXCEPTION: panika i syrena — "STOP! Algorytm w tarapatach! Zatrzymaliśmy wykonanie, żeby nie było katastrofy".

Każdy z tych poziomów ma swoje zastosowanie i ważne, żeby dobrze wybrać, którego użyć.

Tak wyglądają te wiadomości w kodzie:

DO $$
BEGIN
    -- Poziom NOTICE (wszystko OK, tylko info)
    RAISE NOTICE 'Po prostu info: zaczęło się przetwarzanie danych';

    -- Poziom WARNING (coś podejrzanego)
    RAISE WARNING 'Ostrzeżenie: format danych w kolumnie może być niepoprawny';

    -- Poziom EXCEPTION (krytyczny błąd)
    RAISE EXCEPTION 'Błąd: wartość wejściowa jest niedozwolona!';
END $$;

Kiedy używać:

  • RAISE NOTICE — do debugowania i spokojnego wypisywania informacji.
  • RAISE WARNING — żeby ostrzec o potencjalnie złych danych.
  • RAISE EXCEPTION — gdy dzieją się krytyczne błędy i trzeba zatrzymać funkcję.

Obsługa błędów z RAISE EXCEPTION

RAISE EXCEPTION — to twój hamulec bezpieczeństwa. Jeśli coś idzie nie tak, możesz zatrzymać wykonanie funkcji i zgłosić błąd.

Przypomnijmy, podstawowe użycie wygląda tak:

RAISE EXCEPTION 'Twoja wiadomość o błędzie';

Ale żeby wiadomości były bardziej konkretne, możesz użyć zmiennych:

DECLARE
    input_value INTEGER;
BEGIN
    input_value := NULL;

    IF input_value IS NULL THEN
        RAISE EXCEPTION 'Błąd: wartość wejściowa NULL. Oczekiwano wartości INTEGER';
    END IF;
END;

Formatowanie wiadomości

Możesz wstawiać zmienne bezpośrednio do tekstu wiadomości:

DECLARE
    var1 TEXT := 'Dane';
    var2 INTEGER := 42;
BEGIN
    RAISE EXCEPTION 'Błąd podczas przetwarzania % z ID %', var1, var2;
END;

Wynik: Błąd podczas przetwarzania Dane z ID 42.

Przykład: walidacja danych

Wyobraź sobie, że masz procedurę, która przyjmuje wiek człowieka. Jeśli wiek jest ujemny, logiczne jest rzucić błąd:

CREATE OR REPLACE FUNCTION validate_age(age INTEGER)
RETURNS VOID AS $$
BEGIN
    IF age < 0 THEN
        RAISE EXCEPTION 'Wiek nie może być ujemny: %', age;
    END IF;
END;
$$ LANGUAGE plpgsql;

-- Wywołanie funkcji
SELECT validate_age(-5);  -- Rzuci błąd

Informowanie z RAISE NOTICE

Jeśli RAISE EXCEPTION to syrena, to RAISE NOTICE to kumpelskie poklepanie po ramieniu. Dzięki temu poziomowi możesz wrzucać komentarze, żeby ogarnąć, co się dzieje w środku funkcji.

Kiedy używać RAISE NOTICE:

  • Wypisywanie informacji do debugowania (np. aktualny stan zmiennych).
  • Info o rozpoczęciu etapu albo wyniku obliczeń.

Przykład: wiadomości informacyjne

CREATE OR REPLACE FUNCTION calculate_discount(price NUMERIC, discount_rate NUMERIC)
RETURNS NUMERIC AS $$
DECLARE
    final_price NUMERIC;
BEGIN
    RAISE NOTICE 'Cena przed rabatem: %', price;
    RAISE NOTICE 'Stawka rabatu: %', discount_rate;

    final_price := price - (price * discount_rate);

    RAISE NOTICE 'Cena końcowa: %', final_price;

    RETURN final_price;
END;
$$ LANGUAGE plpgsql;

-- Wywołanie funkcji
SELECT calculate_discount(100, 0.2);
-- Wypisze:
-- NOTICE: Cena przed rabatem: 100
-- NOTICE: Stawka rabatu: 0.2
-- NOTICE: Cena końcowa: 80

Zastosowanie praktyczne: planowanie i logowanie

Załóżmy, że masz złożoną procedurę przetwarzania danych i chcesz wiedzieć, na którym etapie właśnie jest:

CREATE OR REPLACE FUNCTION process_data_step_by_step()
RETURNS VOID AS $$
BEGIN
    RAISE NOTICE 'Krok 1: Przygotowanie danych';
    -- Twoja logika dla pierwszego etapu

    RAISE NOTICE 'Krok 2: Walidacja danych';
    -- Twoja logika dla drugiego etapu

    RAISE NOTICE 'Krok 3: Zapis danych';
    -- Twoja logika dla trzeciego etapu
END;
$$ LANGUAGE plpgsql;

-- Wywołanie funkcji
SELECT process_data_step_by_step();
-- W logach pojawi się krok po kroku

Jeszcze jeden przykład. Wyobraźmy sobie sklep, który daje rabaty tylko dla zamówień powyżej określonej kwoty:

CREATE OR REPLACE FUNCTION apply_discount(order_amount NUMERIC)
RETURNS NUMERIC AS $$
BEGIN
    IF order_amount < 50 THEN
        RAISE EXCEPTION 'Błąd: kwota zamówienia musi być co najmniej 50, aktualna kwota: %', order_amount;
    END IF;

    RETURN order_amount * 0.9;  -- Nakładamy 10% rabatu
END;
$$ LANGUAGE plpgsql;

-- Wywołanie funkcji
SELECT apply_discount(30);  -- Błąd: kwota zamówienia musi być co najmniej 50

Typowe błędy

Błąd 1: logowanie wiadomości bez parametrów.

Wygląda mało informacyjnie, szczególnie w dużych procedurach:

RAISE NOTICE 'Wystąpił błąd';  -- Dlaczego? Gdzie? Jak?

Rekomendacja: zawsze dodawaj kontekst:

RAISE NOTICE 'Błąd w funkcji process_data(): wartość wejściowa: %', input_value;

Błąd 2: używanie RAISE EXCEPTION tam, gdzie wystarczy RAISE WARNING.

Jeśli przesadzisz z wyjątkami, kod będzie się przerywał z byle powodu, co utrudni przetwarzanie danych.

Wskazówka: używaj poziomów logowania świadomie. Do debugowania wybieraj NOTICE, a do krytycznych sytuacji — EXCEPTION.

Błąd 3: brak logowania w ogóle.

To jak szukanie kluczy w ciemnym pokoju. Bez logów debugowanie złożonych procesów jest prawie niemożliwe.

Wskazówka: dodawaj RAISE NOTICE na kluczowych etapach działania funkcji, szczególnie jeśli jest duża i skomplikowana.

2
Zadanie
SQL SELF, poziom 55, lekcja 2
Niedostępne
Logowanie błędów podczas walidacji danych
Logowanie błędów podczas walidacji danych
Komentarze
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION