CodeGym /Corsi /SQL SELF /Analisi degli errori tipici nella creazione delle funzion...

Analisi degli errori tipici nella creazione delle funzioni

SQL SELF
Livello 50, Lezione 4
Disponibile

Oggi analizziamo gli errori tipici che si fanno quando si creano funzioni, perché succedono e come risolverli. Solo facendo debug si diventa veri maestri del mestiere — il coding! Let's debug it!

Creare funzioni, soprattutto quando si inizia a studiare PL/pgSQL, può sembrare una roba complicata. Anche i dev più esperti su PostgreSQL ci cascano ogni tanto. Vediamoli uno per uno.

1. Dimenticare la parola chiave RETURNS

PL/pgSQL è super rigido su come descrivi le funzioni. Uno degli errori più comuni è dimenticare di specificare il tipo di dato che la funzione deve restituire. Guarda qui:

-- Errore: manca la parola chiave RETURNS
CREATE FUNCTION incorrect_function() AS $$
BEGIN
    RETURN 1;
END;
$$ LANGUAGE plpgsql;

PostgreSQL non capisce cosa dovrebbe restituire questa funzione. RETURNS è obbligatorio e serve a dire che tipo di dato torna (tipo RETURNS INT, RETURNS TEXT o anche RETURNS VOID).

Soluzione: aggiungi la parola chiave RETURNS con il tipo di dato:

CREATE FUNCTION correct_function() RETURNS INT AS $$
BEGIN
    RETURN 1;
END;
$$ LANGUAGE plpgsql;

2. Restituire un risultato senza RETURN

Chi inizia spesso si dimentica che in PL/pgSQL, per restituire qualcosa, bisogna usare proprio l’operatore RETURN. Ecco un esempio:

-- Errore: manca RETURN
CREATE FUNCTION missing_return() RETURNS TEXT AS $$
BEGIN
    'Ciao, Mondo!'; -- Solo una stringa, ma non restituita
END;
$$ LANGUAGE plpgsql;

Qui la stringa 'Ciao, Mondo!' è solo scritta, ma non viene restituita. PostgreSQL lo vede come un risultato non raggiunto e lancia errore.

Soluzione: aggiungi l’operatore RETURN esplicitamente:

CREATE FUNCTION fixed_return() RETURNS TEXT AS $$
BEGIN
    RETURN 'Ciao, Mondo!';
END;
$$ LANGUAGE plpgsql;

3. Provare a scrivere dati in una variabile non dichiarata

In PL/pgSQL, prima di usare una variabile, la devi dichiarare nel blocco DECLARE. Tipo così:

-- Errore: variabile my_var non dichiarata
CREATE FUNCTION missing_variable() RETURNS VOID AS $$
BEGIN
    my_var := 'Ciao, Mondo!';
END;
$$ LANGUAGE plpgsql;

PostgreSQL non sa che esiste la variabile my_var, perché non è stata dichiarata nel blocco DECLARE.

Soluzione: dichiara sempre le variabili in DECLARE:

CREATE FUNCTION declared_variable() RETURNS VOID AS $$
DECLARE
    my_var TEXT;
BEGIN
    my_var := 'Ciao, Mondo!';
END;
$$ LANGUAGE plpgsql;

4. Uso sbagliato del tipo di ritorno VOID

Il tipo VOID vuol dire che la funzione non restituisce niente. A volte si prova a usare RETURN in funzioni con tipo VOID, e questo crea errori:

-- Errore: RETURN in funzione con VOID
CREATE FUNCTION void_example() RETURNS VOID AS $$
BEGIN
    RETURN 1; -- Restituire un valore non va bene
END;
$$ LANGUAGE plpgsql;

Le funzioni con tipo di ritorno VOID non devono restituire valori. Puoi usare RETURN, ma senza valore.

Soluzione: o togli RETURN, oppure lascialo senza valore:

CREATE FUNCTION correct_void() RETURNS VOID AS $$
BEGIN
    -- Facciamo solo delle azioni
    RAISE NOTICE 'Questa funzione non restituisce niente';
    RETURN; -- Fine funzione
END;
$$ LANGUAGE plpgsql;

5. Uso sbagliato di RAISE per il debug

Per fare debug in PL/pgSQL si usa spesso RAISE NOTICE. Ma se sbagli formato o variabili, arrivano errori.

Esempio:

-- Errore: formato sbagliato
CREATE FUNCTION debug_example() RETURNS VOID AS $$
BEGIN
    RAISE NOTICE 'Il valore è %'; -- Variabile mancante
END;
$$ LANGUAGE plpgsql;

L’operatore RAISE si aspetta che dopo % ci sia una variabile o un valore. Se lasci % da solo, PostgreSQL non sa che fare.

Soluzione: assicurati che variabili o valori siano messi giusti:

CREATE FUNCTION fixed_debug() RETURNS VOID AS $$
DECLARE
    my_var TEXT := 'PostgreSQL';
BEGIN
    RAISE NOTICE 'Il valore è %', my_var; -- Variabile inserita
END;
$$ LANGUAGE plpgsql;

6. Problemi con nomi di variabili e colonne

Se il nome di una variabile è uguale a quello di una colonna, possono succedere cose strane. Tipo così:

-- Errore: conflitto tra nome variabile e colonna
CREATE FUNCTION name_conflict() RETURNS TEXT AS $$
DECLARE
    name TEXT;
BEGIN
    SELECT name INTO name FROM students LIMIT 1; -- Quale name viene usato?
    RETURN name;
END;
$$ LANGUAGE plpgsql;

PL/pgSQL dà priorità alle variabili rispetto ai nomi delle colonne se coincidono.

Soluzione: usa alias per le tabelle o evita nomi uguali.

CREATE FUNCTION fixed_conflict() RETURNS TEXT AS $$
DECLARE
    student_name TEXT;
BEGIN
    SELECT s.name INTO student_name FROM students s LIMIT 1;
    RETURN student_name;
END;
$$ LANGUAGE plpgsql;

7. Esecuzione sbagliata di query nei cicli

Gli errori capitano spesso quando si prova a fare query SQL dentro i cicli. Tipo così:

-- Errore: query sbagliata dentro il ciclo
CREATE FUNCTION cycle_error() RETURNS VOID AS $$
BEGIN
    FOR rec IN SELECT * FROM students LOOP
        EXECUTE 'UPDATE students SET active = TRUE WHERE id = ' || rec.id;
    END LOOP;
END;
$$ LANGUAGE plpgsql;

SQL-injection... Pericolo! Concatenare stringhe per le query SQL è una brutta pratica. Così rischi vulnerabilità.

Per risolvere, usa i parametri:

CREATE FUNCTION safe_cycle() RETURNS VOID AS $$
BEGIN
    FOR rec IN SELECT * FROM students LOOP
        EXECUTE 'UPDATE students SET active = TRUE WHERE id = $1' USING rec.id;
    END LOOP;
END;
$$ LANGUAGE plpgsql;

8. Errori con i tipi di dati

Esempio di errore:

-- Errore: tipi di dati non corrispondenti
CREATE FUNCTION type_error() RETURNS INT AS $$
DECLARE
    my_var TEXT := 'non_un_numero';
BEGIN
    RETURN my_var; -- Errore restituendo testo invece di INT
END;
$$ LANGUAGE plpgsql;

PostgreSQL si aspetta INT, ma riceve TEXT. I tipi di dati devono sempre combaciare.

Come risolvere? Assicurati che i tipi siano giusti, oppure fai una conversione esplicita:

CREATE FUNCTION type_correct() RETURNS INT AS $$
DECLARE
    my_var TEXT := '42';
BEGIN
    RETURN my_var::INT; -- Conversione da testo a numero
END;
$$ LANGUAGE plpgsql;

Best practice e consigli

  • Dividi le funzioni complesse in più piccole. Così il debug e i test sono più facili.
  • Usa i commenti dentro le funzioni per spiegare le parti complicate.
  • Testa sempre le funzioni su pochi dati prima di usarle sulle tabelle vere.
  • Fai debug con RAISE NOTICE, così capisci cosa succede passo passo.
  • Evita le SQL-injection: usa i parametri nelle query.
-- Uso di RAISE per il debug
DO $$
DECLARE
    total_students INT;
BEGIN
    SELECT COUNT(*) INTO total_students FROM students;
    RAISE NOTICE 'Studenti totali: %', total_students; -- Messaggio di debug
END;
$$;

Questi consigli ti risparmieranno un sacco di mal di testa e ti faranno evitare per sempre le "trappole" di PL/pgSQL!

2
Compito
SQL SELF, livello 50, lezione 4
Bloccato
Debug con RAISE NOTICE
Debug con RAISE NOTICE
1
Sondaggio/quiz
Creazione di funzioni semplici, livello 50, lezione 4
Non disponibile
Creazione di funzioni semplici
Creazione di funzioni semplici
Commenti
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION