Avant d’attaquer le sujet principal, faisons un stop sur les erreurs et oublis les plus fréquents que tu risques de croiser. Les bugs en SQL, c’est la galère de tout dev, et bien sûr, ils arrivent toujours au pire moment.
1. Erreurs de syntaxe : "j’ai oublié de fermer IF"
Les erreurs de syntaxe, c’est la base, mais crois-moi, ça arrive plus souvent que tu ne le penses. Par exemple, si tu oublies de fermer un bloc conditionnel IF avec END IF;, le compilateur va direct te juger.
Exemple d’erreur :
CREATE OR REPLACE FUNCTION check_number(num INTEGER)
RETURNS TEXT AS $$
BEGIN
IF num > 0 THEN
RETURN 'Positif';
ELSE
RETURN 'Négatif';
-- quelque part, le END IF; s’est perdu
END;
$$ LANGUAGE plpgsql;
Si tu tentes d’exécuter ce code, tu vas avoir une erreur : ERROR: syntax error at or near "END". Pourquoi ? Parce que le bloc IF est resté ouvert.
Comment éviter ce genre d’erreurs ?
Utilise toujours une structure de code claire. Quand tu ouvres un bloc (genre IF), écris direct sa fermeture. Voilà la version corrigée :
CREATE OR REPLACE FUNCTION check_number(num INTEGER)
RETURNS TEXT AS $$
BEGIN
IF num > 0 THEN
RETURN 'Positif';
ELSE
RETURN 'Négatif';
END IF; -- n’oublie pas de fermer le bloc
END;
$$ LANGUAGE plpgsql;
2. Oublier de gérer tous les cas dans CASE : "Et si je tombe dans aucun cas ?"
Quand tu utilises CASE, pense toujours à mettre une branche ELSE pour gérer les comportements inattendus. Sinon, tu risques de te retrouver avec un NULL pas prévu.
Exemple d’erreur :
CREATE OR REPLACE FUNCTION grade_result(grade CHAR)
RETURNS TEXT AS $$
BEGIN
RETURN CASE grade
WHEN 'A' THEN 'Excellent'
WHEN 'B' THEN 'Bien'
WHEN 'C' THEN 'Moyen'
-- Et si grade = 'D' ou une autre note ?
END;
END;
$$ LANGUAGE plpgsql;
Si tu passes la valeur D, la fonction va renvoyer NULL, ce qui peut foutre le bazar dans ton code.
Version corrigée :
CREATE OR REPLACE FUNCTION grade_result(grade CHAR)
RETURNS TEXT AS $$
BEGIN
RETURN CASE grade
WHEN 'A' THEN 'Excellent'
WHEN 'B' THEN 'Bien'
WHEN 'C' THEN 'Moyen'
ELSE 'Note inconnue' -- On capte tous les autres cas
END;
END;
$$ LANGUAGE plpgsql;
3. Problèmes de boucles infinies : "Pourquoi le serveur freeze ?"
Quand tu utilises une boucle LOOP, c’est facile d’oublier la condition de sortie. Résultat : exécution infinie !
Exemple d’erreur :
CREATE OR REPLACE FUNCTION infinite_loop_demo()
RETURNS VOID AS $$
DECLARE
i INTEGER := 1;
BEGIN
LOOP
i := i + 1;
-- Pas de condition de sortie !
END LOOP;
END;
$$ LANGUAGE plpgsql;
Ce code va faire ramer le serveur, parce que la boucle ne s’arrête jamais.
Comment corriger :
Ajoute une condition de sortie avec 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; -- Condition de sortie
END IF;
END LOOP;
END;
$$ LANGUAGE plpgsql;
4. Sauter des itérations dans les boucles : "Et les données manquantes alors ?"
Quand tu utilises CONTINUE pour sauter des itérations, tu peux te planter si tu ne gères pas tous les cas. Par exemple :
Exemple d’erreur :
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; -- On saute juste les valeurs paires
END IF;
RAISE NOTICE 'Nombre impair : %', i;
END LOOP;
END;
$$ LANGUAGE plpgsql;
Et si tous les nombres sont pairs ? Le serveur tourne, mais tu ne vois rien s’afficher.
Comment corriger :
Assure-toi de bien gérer toutes les données, et ajoute des logs pour contrôler :
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 'On saute le nombre pair : %', i;
CONTINUE;
END IF;
RAISE NOTICE 'Nombre impair : %', i;
END LOOP;
END;
$$ LANGUAGE plpgsql;
Maintenant tu vois quels nombres ont été zappés.
5. Mauvaise gestion des erreurs : "Où est mon RAISE EXCEPTION ?"
Gérer les erreurs avec RAISE EXCEPTION, c’est puissant, mais tu peux vite te planter si tu l’utilises mal.
Exemple d’erreur :
CREATE OR REPLACE FUNCTION calculate_square(num INTEGER)
RETURNS INTEGER AS $$
BEGIN
IF num < 0 THEN
RAISE 'Les nombres négatifs sont interdits !';
END IF;
RETURN num * num;
END;
$$ LANGUAGE plpgsql;
Ce code va planter, car la syntaxe de RAISE est fausse (il manque le niveau du message).
Version corrigée :
CREATE OR REPLACE FUNCTION calculate_square(num INTEGER)
RETURNS INTEGER AS $$
BEGIN
IF num < 0 THEN
RAISE EXCEPTION 'Les nombres négatifs sont interdits !';
END IF;
RETURN num * num;
END;
$$ LANGUAGE plpgsql;
6. Erreurs de logging : "Pourquoi mes erreurs ne s’écrivent pas dans error_log ?"
Un mauvais insert dans la table error_log peut arriver à cause d’erreurs dans les requêtes INSERT INTO.
Exemple d’erreur :
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); -- Et si les colonnes ont changé ?
END;
$$ LANGUAGE plpgsql;
Si dans la table error_log le nom de colonne a changé (genre error_msg), ça va planter.
Comment éviter :
Vérifie toujours la structure de ta table ou utilise un schéma strict pour gérer tes données.
7. L’inattention et le "facteur humain"
Les erreurs ne sont pas que techniques, il y a aussi l’inattention. Un debug oublié, des variables inutilisées ou un code pas formaté, et ta fonction devient vite incompréhensible.
Exemple :
DECLARE
i INTEGER; -- Pourquoi, si la variable ne sert à rien ?
Correction : vire les bouts de code inutiles pour garder ton code clean et lisible.
Maintenant, t’es prêt à éviter les erreurs les plus courantes en PL/pgSQL et à écrire du code qui fait plaisir au lieu de faire mal. N’oublie pas de tester, logger et corriger les bugs à temps — tu vas t’épargner plein de stress et d’appels de clients !
GO TO FULL VERSION