Allez, on va creuser un peu plus PL/pgSQL et commencer à l'utiliser pour de vrai.
Bloc de code
Un bloc de code en PL/pgSQL, c'est l'élément de base du langage. On peut dire que c'est le squelette sur lequel reposent nos fonctions, procédures et toute la magie qui va avec. Le bloc permet d'exécuter la logique, de manipuler les données, de gérer les erreurs, tout ça dans un seul "container".
Les blocs PL/pgSQL sont structurés et comprennent trois parties principales :
DECLARE: déclaration des variables (optionnel).BEGIN ... END: le bloc principal où la logique s'exécute.EXCEPTION: gestion des erreurs (optionnel).
Pour ceux qui aiment les analogies : imagine une recette de cuisine. Même si le texte commence par la liste des ingrédients, la vraie magie se passe pendant la préparation. En termes PL/pgSQL :
DECLARE— c'est la liste des ingrédients (les variables).BEGIN ... END— c'est là où on mélange, on fait cuire, on fait revenir.EXCEPTION— c'est le plan B si jamais tu crames un truc.
Syntaxe d'un bloc PL/pgSQL
D'abord, on regarde la structure générale du bloc, comme un "squelette". Après, on rajoute la viande (ou du fromage végé si tu préfères) — la logique concrète.
DO $$
DECLARE
-- Ici on déclare les variables
student_count INT;
BEGIN
-- Ici on met la logique
SELECT COUNT(*) INTO student_count FROM students;
RAISE NOTICE 'Nombre total d''étudiants : %', student_count;
EXCEPTION
-- Ici on gère les erreurs
WHEN OTHERS THEN
RAISE NOTICE 'Une erreur est survenue.';
END;
$$;
On va décortiquer ça étape par étape.
DECLARE— ici on déclare nos variables. Le truc cool, c'est que PL/pgSQL supporte quasi tous les types de données de PostgreSQL — du simpleINTEGERau plus exotique JSONB. Pour déclarer une variable, tu mets son nom, son type, et si tu veux, une valeur initiale.
Exemple :
DECLARE
student_name TEXT; -- Variable pour le nom de l'étudiant
course_count INT := 0; -- On met la valeur initiale à 0
is_graduated BOOLEAN; -- Variable booléenne
Fais gaffe, les variables peuvent être initialisées (comme course_count) ou pas.
BEGIN ... END— le bloc principal d'exécution.
Cette partie du bloc s'occupe de la logique principale. Ici, tu peux :
- Faire des requêtes SQL (
SELECT,INSERT, etc.). - Manipuler des données.
- Utiliser des structures de contrôle (
IF,LOOP, etc.). - Afficher des messages de debug avec
RAISE.
Exemple :
BEGIN
SELECT COUNT(*) INTO student_count FROM students;
IF student_count > 0 THEN
RAISE NOTICE 'On a des étudiants !';
ELSE
RAISE NOTICE 'Aucun étudiant trouvé.';
END IF;
END;
EXCEPTION— gestion des erreurs (optionnel).
Si une erreur se produit pendant l'exécution du bloc, la section EXCEPTION te permet de l'attraper et de faire un truc utile — genre afficher un message ou exécuter un code alternatif.
Exemple :
BEGIN
SELECT COUNT(*) INTO student_count FROM non_existing_table; -- Erreur !
EXCEPTION
WHEN OTHERS THEN
RAISE NOTICE 'Oups, un truc a foiré !';
END;
Exemple concret : compter les étudiants
Maintenant, on assemble tout dans un exemple qui peut servir dans la vraie vie. On va écrire un bloc PL/pgSQL qui compte le nombre d'étudiants dans la table students et affiche un message.
DO $$
DECLARE
total_students INT; -- Variable pour stocker le nombre d'étudiants
BEGIN
-- On compte le nombre d'étudiants
SELECT COUNT(*) INTO total_students FROM students;
-- On affiche le message avec le résultat
RAISE NOTICE 'Nombre d''étudiants : %', total_students;
EXCEPTION
-- On gère les erreurs possibles, genre si la table existe pas
WHEN OTHERS THEN
RAISE NOTICE 'Une erreur est survenue lors du comptage des étudiants.';
END;
$$;
Lancer ce bloc va afficher un message dans la console. Par exemple : Nombre d'étudiants : 42.
Particularités de l'utilisation des variables
Regardons quelques points importants :
Affectation de valeurs aux variables. Pour mettre une valeur dans une variable, tu peux utiliser l'opérateur SELECT INTO :
SELECT COUNT(*) INTO total_students FROM students;
Initialisation des variables. Si tu n'as pas donné de valeur à la variable à la déclaration, sa valeur par défaut sera NULL.
Par exemple :
DECLARE
my_var INT; -- Valeur NULL
Variables de type RECORD. C'est un type de variable universel, tu peux y mettre une ligne d'une table. Exemple :
DECLARE
student RECORD;
BEGIN
SELECT * INTO student FROM students WHERE id = 1;
RAISE NOTICE 'Nom de l''étudiant : %, Âge : %', student.name, student.age;
END;
Exemple : compter les cours d'un étudiant
On va résoudre un cas pratique : compter combien de cours un étudiant a, et afficher le résultat.
DO $$
DECLARE
student_id INT := 1; -- ID de l'étudiant
course_count INT; -- Variable pour le nombre de cours
BEGIN
-- On compte le nombre de cours
SELECT COUNT(*) INTO course_count
FROM enrollments
WHERE student_id = student_id;
-- On affiche le message
RAISE NOTICE 'L''étudiant ID % est inscrit à % cours.', student_id, course_count;
EXCEPTION
WHEN OTHERS THEN
RAISE NOTICE 'Une erreur est survenue lors du traitement de l''étudiant ID %', student_id;
END;
$$;
Ce bloc est flexible : tu peux changer student_id pour voir combien de cours ont différents étudiants.
Erreurs et comment les éviter
Si PL/pgSQL te fait déjà l'effet d'un hot-dog qui explose dans le micro-ondes, t'inquiète, c'est normal. Au début, tu vas sûrement tomber sur des erreurs "classiques". Voilà quelques exemples :
Oubli de déclaration de variable. Si t'as oublié de déclarer une variable avec DECLARE, PL/pgSQL va râler que la variable "n'existe pas".
Essayer d'utiliser NULL comme valeur. Si la variable a été déclarée mais pas initialisée, elle vaut NULL. Ça peut donner des comportements chelous. Par exemple :
IF my_var = NULL THEN -- Ça marche PAS !
Utilise IS NULL :
IF my_var IS NULL THEN
Mauvaise utilisation de la section EXCEPTION. Parfois, les devs attrapent toutes les erreurs (WHEN OTHERS), mais n'écrivent rien à faire. Ça peut cacher le vrai souci. Mieux vaut afficher un message d'erreur :
RAISE NOTICE 'Erreur : %', SQLERRM;
GO TO FULL VERSION