CodeGym /Kursy /SQL SELF /Obsługa błędów podczas wstawiania i aktualizacji danych

Obsługa błędów podczas wstawiania i aktualizacji danych

SQL SELF
Poziom 22 , Lekcja 3
Dostępny

Przeanalizujmy typowe błędy podczas wstawiania nowych danych do tabeli.

Błąd 1: Próba wstawienia NULL do obowiązkowego pola

PostgreSQL pilnuje, żeby zasady bazy były przestrzegane. Zobaczmy przykłady ograniczeń, które mogą być źródłem błędów:

CREATE TABLE students (
    id SERIAL PRIMARY KEY,
    name TEXT NOT NULL, -- Imię nie może być NULL
    age INT
);

-- Błąd: pole name jest obowiązkowe
INSERT INTO students (name, age) VALUES (NULL, 20);

Wynik: błąd null value in column "name" of relation "students" violates not-null constraint`.

Musisz pilnować, jakie dane dodajesz. Może ta kolumna kiedyś pozwalała na NULL, ale teraz jest obowiązkowa.

Błąd 2: Duplikacja danych w unikalnej kolumnie.

CREATE TABLE courses (
    course_id SERIAL PRIMARY KEY,
    course_name TEXT UNIQUE -- Nazwa kursu musi być unikalna
);

-- Pierwsze wstawienie się udaje
INSERT INTO courses (course_name) VALUES ('SQL Basics');

-- Drugie wstawienie powoduje błąd
INSERT INTO courses (course_name) VALUES ('SQL Basics');

Wynik: błąd duplicate key value violates unique constraint`.

Zwykle to nie jest Twój błąd, użytkownik próbuje przypadkowo wykonać jakąś akcję drugi raz. W tej sytuacji nie musisz nic robić.

Błąd 3: Naruszenie spójności referencyjnej.

CREATE TABLE enrollments (
    enrollment_id SERIAL PRIMARY KEY,
    student_id INT REFERENCES students(id), -- Musi istnieć student z takim ID
    course_id INT REFERENCES courses(course_id)
);

-- Błąd: student z ID = 99 nie istnieje
INSERT INTO enrollments (student_id, course_id) VALUES (99, 1);

Wynik: błąd insert or update on table "enrollments" violates foreign key constraint`.

Super, że pojawił się błąd. Nie ma nic gorszego niż naruszenie spójności bazy. Najprawdopodobniej w kodzie obsługującym bazę jest błąd albo jakieś dane są nieaktualne. Tak czy inaczej, jeśli baza nie pozwoliła naruszyć swojej spójności — to bardzo dobrze.

Obsługa błędów w PostgreSQL

Tak, błędy się zdarzają. Ale ważne jest nie tylko je zauważyć, ale też umieć sobie z nimi radzić.

Transakcje jako narzędzie ochrony

Pracując z danymi często używamy transakcji, żeby zapewnić spójność danych. Jeśli pojawi się błąd, możemy cofnąć zmiany.

Przykład: dodawanie danych do dwóch tabel.

BEGIN; -- Startujemy transakcję

-- Wstawiamy dane do tabeli students
INSERT INTO students (name, age) VALUES ('Otto Lin', 21);

-- Wstawiamy wpis do tabeli enrollments
-- Tu pojawi się błąd, jeśli kurs z ID=10 nie istnieje
INSERT INTO enrollments (student_id, course_id) VALUES (1, 10);

-- Jeśli wszystko się udało
COMMIT;
-- Jeśli był błąd, cofamy zmiany
ROLLBACK;

Jeśli kurs z course_id = 10 nie istnieje, wstawienie do tabeli students też zostanie cofnięte.

Obsługa błędów w transakcjach

W PostgreSQL możesz przewidzieć błędy i obsłużyć je bezpośrednio w zapytaniach używając bloków EXCEPTION.

Przykład: dodajemy studenta i zapisujemy go na kurs. Jeśli pojawi się błąd, wpis o błędzie trafia do loga.

DO $$
BEGIN
    -- Próbujemy wstawić dane
    INSERT INTO students (name, age) VALUES ('Anna Song', 22);
    INSERT INTO enrollments (student_id, course_id) VALUES (2, 999); -- Błąd

    -- Jeśli wszystko się udało
    RAISE NOTICE 'Wpis został pomyślnie dodany!';
EXCEPTION
    WHEN foreign_key_violation THEN
        -- Obsługujemy naruszenie klucza obcego
        RAISE WARNING 'Kurs z podanym course_id nie istnieje.';
END $$;

Sprawdzanie unikalności za pomocą ON CONFLICT

Możesz z góry zapobiec błędowi związanemu z naruszeniem ograniczenia UNIQUE używając konstrukcji ON CONFLICT. Pozwala to określić, co zrobić w przypadku konfliktu.

Przykład: jeśli próbujesz wstawić duplikat kursu, pomijamy wstawienie.

INSERT INTO courses (course_name)
    VALUES ('SQL Basics')
ON CONFLICT (course_name) DO NOTHING; -- Pomiń duplikat

Albo zaktualizujemy istniejący wiersz:

INSERT INTO courses (course_name)
    VALUES ('SQL Basics')
ON CONFLICT (course_name) DO UPDATE     
    SET course_name = EXCLUDED.course_name || ' (Updated)';

Więcej o operatorze ON CONFLICT opowiem na kolejnym poziomie, gdy będziemy omawiać masowe ładowanie danych :P

Typowe błędy pracy z danymi i jak ich unikać

Już widziałeś, że główne źródła błędów to:

  1. Naruszenie ograniczeń (NOT NULL, UNIQUE, FOREIGN KEY).
  2. Brak warunków w zapytaniach (WHERE) podczas aktualizacji lub usuwania danych.
  3. Błędy w kolejności wykonywania transakcji.

Żeby się zabezpieczyć:

  • Używaj transakcji i ROLLBACK przy większych operacjach.
  • Zawsze sprawdzaj dane przed wstawieniem.
  • Loguj błędy do analizy.
  • Stosuj ON CONFLICT, żeby uniknąć powtarzających się wpisów.

Teraz jesteś uzbrojony w wiedzę do walki z błędami! Pamiętaj: dobry programista to nie ten, kto nie popełnia błędów, ale ten, kto potrafi je naprawiać.

Komentarze
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION