Gestione degli errori durante l'inserimento e l'aggiornamento dei dati
Dai, vediamo insieme gli errori più comuni quando provi a inserire nuovi dati in una tabella.
Errore 1: Tentativo di inserire NULL in un campo obbligatorio
PostgreSQL tiene d'occhio che le regole del database vengano rispettate. Ecco alcuni esempi di constraint che possono causare errori:
CREATE TABLE students (
id SERIAL PRIMARY KEY,
name TEXT NOT NULL, -- Il nome non può essere NULL
age INT
);
-- Errore: il campo name è obbligatorio
INSERT INTO students (name, age) VALUES (NULL, 20);
Risultato: errore null value in column "name" of relation "students" violates not-null constraint`.
Devi sempre controllare quali dati stai aggiungendo. Magari prima questa colonna accettava NULL, ma ora è diventata obbligatoria.
Errore 2: Duplicazione dei dati in una colonna unica.
CREATE TABLE courses (
course_id SERIAL PRIMARY KEY,
course_name TEXT UNIQUE -- Il nome del corso deve essere unico
);
-- Il primo inserimento va a buon fine
INSERT INTO courses (course_name) VALUES ('SQL Basics');
-- Il secondo inserimento genera un errore
INSERT INTO courses (course_name) VALUES ('SQL Basics');
Risultato: errore duplicate key value violates unique constraint`.
Di solito non è colpa tua, magari l'utente sta cercando di ripetere per sbaglio un'azione. In questa situazione non devi fare nulla.
Errore 3: Violazione dell'integrità referenziale.
CREATE TABLE enrollments (
enrollment_id SERIAL PRIMARY KEY,
student_id INT REFERENCES students(id), -- Deve esistere uno studente con questo ID
course_id INT REFERENCES courses(course_id)
);
-- Errore: lo studente con ID = 99 non esiste
INSERT INTO enrollments (student_id, course_id) VALUES (99, 1);
Risultato: errore insert or update on table "enrollments" violates foreign key constraint`.
In realtà è un bene che sia uscito un errore. Non c'è niente di peggio che rompere l'integrità del database. Probabilmente c'è un bug nel codice che lavora col database, oppure alcuni dati sono vecchi. In ogni caso, se il database non ti lascia rompere la sua integrità — è una cosa ottima.
Gestione degli errori in PostgreSQL
Sì, gli errori capitano. Ma non basta notarli, bisogna anche saperci lavorare.
Le transazioni come strumento di protezione
Quando lavoriamo coi dati usiamo spesso le transazioni per garantire la coerenza. Se succede un errore, possiamo annullare le modifiche.
Esempio: aggiunta di dati in due tabelle.
BEGIN; -- Iniziamo la transazione
-- Inseriamo dati nella tabella students
INSERT INTO students (name, age) VALUES ('Otto Lin', 21);
-- Inseriamo un record nella tabella enrollments
-- Qui si genera un errore se il corso con ID=10 non esiste
INSERT INTO enrollments (student_id, course_id) VALUES (1, 10);
-- Se tutto è andato bene
COMMIT;
-- Se c'è stato un errore, "annulliamo" le modifiche
ROLLBACK;
Se il corso con course_id = 10 non esiste, anche l'inserimento nella tabella students verrà annullato.
Gestione degli errori nelle transazioni
In PostgreSQL puoi prevedere gli errori e gestirli direttamente nelle query usando i blocchi EXCEPTION.
Esempio: aggiungiamo uno studente e lo iscriviamo a un corso. Se c'è un errore, il messaggio viene scritto nel log.
DO $$
BEGIN
-- Proviamo a inserire i dati
INSERT INTO students (name, age) VALUES ('Anna Song', 22);
INSERT INTO enrollments (student_id, course_id) VALUES (2, 999); -- Errore
-- Se tutto va bene
RAISE NOTICE 'Record aggiunto con successo!';
EXCEPTION
WHEN foreign_key_violation THEN
-- Gestiamo la violazione della foreign key
RAISE WARNING 'Il corso con il course_id specificato non esiste.';
END $$;
Controllo dell'unicità con ON CONFLICT
Puoi prevenire in anticipo l'errore legato alla violazione della constraint UNIQUE usando la costruzione ON CONFLICT. Così puoi specificare cosa fare in caso di conflitto.
Esempio: se provi a inserire un corso duplicato, saltiamo l'inserimento.
INSERT INTO courses (course_name)
VALUES ('SQL Basics')
ON CONFLICT (course_name) DO NOTHING; -- Salta i dati duplicati
Oppure aggiorniamo la riga esistente:
INSERT INTO courses (course_name)
VALUES ('SQL Basics')
ON CONFLICT (course_name) DO UPDATE
SET course_name = EXCLUDED.course_name || ' (Aggiornato)';
Ti racconterò di più sull'operatore ON CONFLICT al prossimo livello, quando parleremo di caricamento massivo dei dati :P
Errori tipici nella gestione dei dati e come evitarli
Hai già visto che le principali fonti di errore sono:
- Violazione delle constraint (
NOT NULL,UNIQUE,FOREIGN KEY). - Mancanza di condizioni nelle query (
WHERE) durante update o delete. - Errori nell'ordine di esecuzione delle transazioni.
Per stare tranquillo:
- Usa le transazioni e
ROLLBACKper le operazioni grosse. - Controlla sempre i dati prima di inserirli.
- Logga gli errori per analizzarli.
- Usa
ON CONFLICTper evitare i duplicati.
Ora sei pronto a combattere gli errori! Ricorda: un bravo dev non è quello che non sbaglia mai, ma quello che sa come rimediare agli errori.
GO TO FULL VERSION