Prima di tutto, fermiamoci sugli errori e le sviste più frequenti che potresti incontrare. Gli errori in SQL sono il tormento di ogni dev, e di solito capitano proprio quando non dovrebbero.
1. Errori di sintassi: "mi sono dimenticato di chiudere IF"
Gli errori di sintassi sono i più basici, ma capitano più spesso di quanto pensi. Per esempio, se ti dimentichi di chiudere un blocco IF con END IF;, il compilatore ti bacchetta subito.
Esempio di errore:
CREATE OR REPLACE FUNCTION check_number(num INTEGER)
RETURNS TEXT AS $$
BEGIN
IF num > 0 THEN
RETURN 'Positivo';
ELSE
RETURN 'Negativo';
-- da qualche parte manca END IF;
END;
$$ LANGUAGE plpgsql;
Se provi a lanciare questo codice, ti becchi l’errore: ERROR: syntax error at or near "END". Perché? Perché il blocco IF è rimasto aperto.
Come evitare questi errori?
Usa sempre una struttura di codice chiara. Quando apri un blocco (tipo IF), scrivi subito anche la chiusura. Ecco la versione corretta:
CREATE OR REPLACE FUNCTION check_number(num INTEGER)
RETURNS TEXT AS $$
BEGIN
IF num > 0 THEN
RETURN 'Positivo';
ELSE
RETURN 'Negativo';
END IF; -- non dimenticare di chiudere il blocco
END;
$$ LANGUAGE plpgsql;
2. Dimenticare di gestire tutti i casi nel CASE: "E se non rientro in nessun caso?"
Quando usi CASE, metti sempre il ramo ELSE per gestire comportamenti inaspettati. Se manca, rischi di beccarti un NULL non voluto.
Esempio di errore:
CREATE OR REPLACE FUNCTION grade_result(grade CHAR)
RETURNS TEXT AS $$
BEGIN
RETURN CASE grade
WHEN 'A' THEN 'Eccellente'
WHEN 'B' THEN 'Buono'
WHEN 'C' THEN 'Nella media'
-- E se grade = 'D' o altro voto?
END;
END;
$$ LANGUAGE plpgsql;
Se passi il valore D, la funzione ti restituisce NULL, e questo può creare problemi nel tuo codice.
Versione corretta:
CREATE OR REPLACE FUNCTION grade_result(grade CHAR)
RETURNS TEXT AS $$
BEGIN
RETURN CASE grade
WHEN 'A' THEN 'Eccellente'
WHEN 'B' THEN 'Buono'
WHEN 'C' THEN 'Nella media'
ELSE 'Voto sconosciuto' -- Prendiamo tutti gli altri casi
END;
END;
$$ LANGUAGE plpgsql;
3. Problemi con i cicli infiniti: "Perché il server si è bloccato?"
Quando usi il ciclo LOOP, è facile dimenticare la condizione di uscita. Così rischi di creare un ciclo infinito:
Esempio di errore:
CREATE OR REPLACE FUNCTION infinite_loop_demo()
RETURNS VOID AS $$
DECLARE
i INTEGER := 1;
BEGIN
LOOP
i := i + 1;
-- Nessuna condizione di uscita!
END LOOP;
END;
$$ LANGUAGE plpgsql;
Questo codice manda in tilt il server perché il ciclo non finisce mai.
Come sistemare:
Aggiungi una condizione di uscita con EXIT:
CREATE OR REPLACE FUNCTION finite_loop_demo()
RETURNS VOID AS $$
DECLARE
i INTEGER := 1;
BEGIN
LOOP
i := i + 1;
IF i > 10 THEN
EXIT; -- Condizione di uscita
END IF;
END LOOP;
END;
$$ LANGUAGE plpgsql;
4. Saltare iterazioni nei cicli: "E i dati mancanti?"
Quando usi CONTINUE per saltare delle iterazioni, puoi sbagliare se non consideri tutti i casi. Per esempio:
Esempio di errore:
CREATE OR REPLACE FUNCTION skip_even()
RETURNS VOID AS $$
DECLARE
i INTEGER := 0;
BEGIN
WHILE i < 10 LOOP
i := i + 1;
IF i % 2 = 0 THEN
CONTINUE; -- Saltiamo i numeri pari
END IF;
RAISE NOTICE 'Numero dispari: %', i;
END LOOP;
END;
$$ LANGUAGE plpgsql;
E se tutti i numeri fossero pari? Il server gira, ma non vedi nessun risultato.
Come sistemare:
Assicurati di gestire tutti i dati correttamente e aggiungi logging per controllare:
CREATE OR REPLACE FUNCTION skip_even_logging()
RETURNS VOID AS $$
DECLARE
i INTEGER := 0;
BEGIN
WHILE i < 10 LOOP
i := i + 1;
IF i % 2 = 0 THEN
RAISE NOTICE 'Salto numero pari: %', i;
CONTINUE;
END IF;
RAISE NOTICE 'Numero dispari: %', i;
END LOOP;
END;
$$ LANGUAGE plpgsql;
Ora vedi quali numeri sono stati saltati.
5. Gestione errori sbagliata: "Dov'è il mio RAISE EXCEPTION?"
Gestire gli errori con RAISE EXCEPTION è una bomba, ma puoi fare casino se lo usi male.
Esempio di errore:
CREATE OR REPLACE FUNCTION calculate_square(num INTEGER)
RETURNS INTEGER AS $$
BEGIN
IF num < 0 THEN
RAISE 'Non è permesso un numero negativo!';
END IF;
RETURN num * num;
END;
$$ LANGUAGE plpgsql;
Questo codice dà errore perché la sintassi di RAISE è sbagliata (manca il livello del messaggio).
Versione corretta:
CREATE OR REPLACE FUNCTION calculate_square(num INTEGER)
RETURNS INTEGER AS $$
BEGIN
IF num < 0 THEN
RAISE EXCEPTION 'Non è permesso un numero negativo!';
END IF;
RETURN num * num;
END;
$$ LANGUAGE plpgsql;
6. Errori nel logging: "Perché i miei errori non finiscono in error_log?"
Scrivere male nella tabella error_log può succedere per errori nelle query INSERT INTO.
Esempio di errore:
CREATE OR REPLACE FUNCTION log_error(err_msg TEXT)
RETURNS VOID AS $$
BEGIN
INSERT INTO error_log (error_message, error_time)
VALUES (err_msg, CURRENT_TIMESTAMP); -- E se c'è un errore nei nomi delle colonne?
END;
$$ LANGUAGE plpgsql;
Se nella tabella error_log hai cambiato il nome della colonna (tipo in error_msg), ti becchi un errore.
Come evitare:
Controlla sempre la struttura della tabella o usa uno schema rigoroso per gestire i dati.
7. Disattenzione generale e "fattore umano"
Gli errori non sono solo tecnici, ma anche dovuti alla distrazione. Debug dimenticato, variabili inutilizzate o codice non formattato possono trasformare la tua funzione in un casino.
Esempio:
DECLARE
i INTEGER; -- Perché, se la variabile non viene usata?
Soluzione: togli le parti inutili dal codice, così resta pulito e chiaro.
Ora sei pronto a evitare gli errori più comuni in PL/pgSQL e scrivere codice che dà più soddisfazione che mal di testa. Ricordati di testare, loggare e fixare i bug al volo — così ti risparmi un sacco di nervi e chiamate dai clienti!
GO TO FULL VERSION