CodeGym /Cours /SQL SELF /Contrôle de l’exécution des fonctions : PERFORM

Contrôle de l’exécution des fonctions : PERFORM

SQL SELF
Niveau 55 , Leçon 3
Disponible

PERFORM dans le monde de PostgreSQL, c’est un peu le héros discret et balèze : il débarque, fait le taf et disparaît sans laisser de traces sous forme de données retournées. Cette commande sert quand tu veux exécuter une requête SQL dans une fonction PL/pgSQL, mais que tu n’as pas besoin de traiter ou de stocker le résultat. Le but principal de PERFORM, c’est de lancer une requête pour provoquer un effet (genre modifier des données ou appeler une autre fonction), pas pour récupérer un résultat.

PERFORM s’utilise quand le résultat de la requête ne t’intéresse pas. Contrairement à un SELECT classique qui attend que tu fasses quelque chose avec le résultat, PERFORM lance juste la requête et passe à la suite, tranquille. C’est super pratique si tu appelles une fonction juste pour son effet de bord, pas pour ce qu’elle retourne. Par exemple, pour écrire un truc dans les logs. Ce genre d’approche rend le code plus simple et plus lisible : moins de blabla, plus d’efficacité.

Exemples d’utilisation de PERFORM

Appeler des fonctions

Voyons un exemple concret. Imagine qu’on a une fonction log_action qui écrit des infos sur les actions de l’utilisateur dans les logs. Cette fonction ne retourne rien, et on veut juste qu’elle s’exécute. Voilà comment faire avec PERFORM :

CREATE OR REPLACE FUNCTION log_action(user_id INT, action TEXT) RETURNS VOID AS $$
BEGIN
    INSERT INTO logs (user_id, action, log_time)
    VALUES (user_id, action, NOW());
END;
$$ LANGUAGE plpgsql;

-- Ensuite, on utilise PERFORM pour appeler cette fonction :
PERFORM log_action(5, 'Utilisateur connecté');

Qu’est-ce qui se passe ici ? La commande PERFORM appelle la fonction log_action, qui ajoute une entrée dans la table logs. Fais bien gaffe : le résultat de l’appel de la fonction est ignoré. On l’utilise juste pour son effet, pas pour ce qu’elle retourne.

Mise à jour de données

Parfois, PERFORM est utile quand tu veux exécuter une requête qui modifie des données sans te soucier du résultat. Par exemple, on va mettre à jour le statut d’une commande dans la table orders.

CREATE OR REPLACE FUNCTION update_order_status(order_id INT, new_status TEXT) RETURNS VOID AS $$
BEGIN
    UPDATE orders
    SET status = new_status
    WHERE id = order_id;
END;
$$ LANGUAGE plpgsql;

-- On utilise PERFORM pour appeler cette fonction :
PERFORM update_order_status(101, 'Expédiée');

Ici, update_order_status met à jour le statut de la commande avec l’identifiant 101. On ne s’intéresse pas au résultat de la requête SQL dans la fonction, donc PERFORM est parfait.

Lancer des opérations auxiliaires

Des fois, les fonctions contiennent des mini-opérations, genre de la logique "auxiliaire" qui aide à finir un processus plus complexe. Par exemple, on veut vider le cache après avoir mis à jour une table :

CREATE OR REPLACE FUNCTION clear_cache() RETURNS VOID AS $$
BEGIN
    DELETE FROM cache_table;
END;
$$ LANGUAGE plpgsql;

-- On l’appelle dans une autre fonction :
CREATE OR REPLACE FUNCTION update_product(product_id INT, new_price NUMERIC) RETURNS VOID AS $$
BEGIN
    UPDATE products
    SET price = new_price
    WHERE id = product_id;

    -- On vide le cache après la mise à jour :
    PERFORM clear_cache();
END;
$$ LANGUAGE plpgsql;

Voilà la magie : tu peux enchaîner les actions en utilisant PERFORM pour appeler des fonctions dont tu n’as rien à faire du résultat.

Exercices pratiques

Regardons quelques exemples de comment PERFORM peut te simplifier la vie de dev.

Exemple 1 : logger les étapes d’une procédure

Imaginons qu’on a une procédure de traitement de paiement bien costaud, et qu’on veut suivre chaque étape en l’écrivant dans les logs. On peut définir une fonction log_stage pour enregistrer l’info, puis utiliser PERFORM :

CREATE OR REPLACE FUNCTION log_stage(stage_name TEXT) RETURNS VOID AS $$
BEGIN
    INSERT INTO process_logs(stage, log_time)
    VALUES (stage_name, NOW());
END;
$$ LANGUAGE plpgsql;

-- Voici un exemple de procédure :
CREATE OR REPLACE FUNCTION process_payment(payment_id INT) RETURNS VOID AS $$
BEGIN
    -- Log du début
    PERFORM log_stage('Début du traitement du paiement');

    -- Première étape
    UPDATE payments
    SET status = 'En cours'
    WHERE id = payment_id;

    PERFORM log_stage('Statut du paiement mis à jour');

    -- Dernière étape
    UPDATE payments
    SET status = 'Terminé'
    WHERE id = payment_id;

    PERFORM log_stage('Paiement terminé');
END;
$$ LANGUAGE plpgsql;

Ici, log_stage est appelée via PERFORM pour enregistrer l’état d’avancement à chaque étape de la procédure. Ça rend le code plus facile à déboguer.

Exemple 2 : activer des notifications

Imagine que tu as un système de notifications, et qu’il faut envoyer une notif après chaque action importante. PERFORM peut servir à appeler la fonction qui s’en occupe :

CREATE OR REPLACE FUNCTION send_notification(user_id INT, message TEXT) RETURNS VOID AS $$
BEGIN
    INSERT INTO notifications (user_id, message, created_at)
    VALUES (user_id, message, NOW());
END;
$$ LANGUAGE plpgsql;

-- Utilisé dans une procédure :
CREATE OR REPLACE FUNCTION complete_task(task_id INT) RETURNS VOID AS $$
DECLARE
    user_id INT;
BEGIN
    -- On récupère l’auteur de la tâche
    SELECT assigned_to INTO user_id
    FROM tasks
    WHERE id = task_id;

    -- On termine la tâche
    UPDATE tasks
    SET status = 'Terminée'
    WHERE id = task_id;

    -- On envoie la notification
    PERFORM send_notification(user_id, 'Ta tâche a été terminée');
END;
$$ LANGUAGE plpgsql;

Ici, PERFORM permet de se concentrer uniquement sur l’effet de bord — envoyer la notif — sans se soucier du résultat de la fonction.

Astuces et erreurs courantes

Quand tu utilises PERFORM, retiens quelques points importants. Par exemple, PERFORM ne vérifie pas si la requête a retourné des données. Ça veut dire que si le résultat de la fonction ou de la requête SQL est important pour la logique, il vaut mieux utiliser SELECT INTO. Regarde cet exemple :

-- Erreur potentielle
PERFORM une_fonction_qui_doit_retourner_une_valeur();

-- Correction
SELECT une_fonction_qui_doit_retourner_une_valeur() INTO une_variable;

Une autre erreur fréquente, c’est d’utiliser PERFORM là où il faudrait vraiment récupérer le résultat de la requête, genre pour valider des données. Dans ces cas-là, évidemment, il faut récupérer et vérifier le résultat.

Dans les vrais projets, la commande PERFORM aide à rendre les fonctions et procédures plus simples, plus lisibles et plus faciles à déboguer. Combinée avec le logging (RAISE NOTICE) et les fonctions de diagnostic intégrées de PostgreSQL comme current_query(), c’est un outil super important pour créer des systèmes fiables, maîtrisés et clairs.

Commentaires
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION