CodeGym /Cours /SQL SELF /Appeler des fonctions depuis des requêtes SQL

Appeler des fonctions depuis des requêtes SQL

SQL SELF
Niveau 50, Leçon 2
Disponible

Imagine que t'as une fonction pour des calculs compliqués ou pour traiter des données. Sans la possibilité d'intégrer la fonction dans les requêtes SQL, tu bosserais comme ça :

  1. Appeler la fonction depuis un langage de programmation (genre Python ou JavaScript).
  2. Passer le résultat dans la requête SQL.

C'est un détour inutile ! Dans PostgreSQL, tu peux intégrer les fonctions direct dans la requête SQL, ça réduit le code, accélère les opérations et limite les allers-retours serveur. C'est super utile pour :

  • Automatiser les calculs.
  • Valider les données avant insertion.
  • Modifier des données existantes.

Appeler des fonctions dans SELECT

On commence simple et on voit comment utiliser une fonction dans une requête SELECT classique. Disons qu'on a une table students avec des infos sur les étudiants. On veut écrire une fonction qui renvoie l'âge actuel d'un étudiant à partir de sa date de naissance.

Étape 1 : écrire la fonction

On crée la fonction calculate_age qui prend une date de naissance et renvoie l'âge :

CREATE OR REPLACE FUNCTION calculate_age(birth_date DATE) RETURNS INT AS $$
BEGIN
    RETURN DATE_PART('year', AGE(NOW(), birth_date))::INT;
END;
$$ LANGUAGE plpgsql;

Étape 2 : utiliser la fonction dans la requête SELECT

Maintenant, on peut appeler cette fonction pour chaque ligne de la table :

SELECT id, name, calculate_age(birth_date) AS age FROM students;

Qu'est-ce qui se passe ?

  • Pour chaque ligne de la table students, la fonction calculate_age calcule l'âge.
  • La valeur retournée s'affiche dans la colonne age.

Exemple de résultat :

id name age
1 Otto 21
2 Anna 25
3 Alex 22

Tu vois, rien de sorcier, et le résultat est clean et pro.

Appeler des fonctions dans INSERT

Les fonctions sont aussi utiles quand tu ajoutes des données. Par exemple, imaginons qu'on a une table logs où on enregistre les actions des utilisateurs. On veut insérer un message de log en générant le texte automatiquement via une fonction.

Étape 1 : créer la fonction

On écrit la fonction generate_log_message qui prend le nom d'utilisateur et l'action, et renvoie le texte du message :

CREATE OR REPLACE FUNCTION generate_log_message(username TEXT, action TEXT) RETURNS TEXT AS $$
BEGIN
    RETURN username || ' a fait l\'action : ' || action || ' à ' || NOW();
END;
$$ LANGUAGE plpgsql;

Étape 2 : utiliser la fonction dans INSERT

Maintenant, on insère le message dans la table logs en appelant la fonction lors de l'ajout de la ligne :

INSERT INTO logs (message)
VALUES (generate_log_message('Otto', 'connexion au site'));

Résultat :

id message
1 Otto a fait l'action : connexion au site à 2023-10-26 12:00:00

La fonction fait tout pour nous : elle gère le formatage du texte et ajoute le timestamp. C'est un super exemple de comment les fonctions peuvent automatiser les tâches chiantes.

Appeler des fonctions dans UPDATE

Les fonctions peuvent aussi servir à modifier des données dans une table. Disons qu'on a la table students et qu'on veut mettre à jour le nom du groupe en utilisant une fonction pour les faire passer au niveau supérieur.

Étape 1 : créer la fonction

On écrit la fonction promote_student qui prend l'ancien groupe (genre 101) et renvoie le nouveau (genre 201) :

CREATE OR REPLACE FUNCTION promote_student(old_group TEXT) RETURNS TEXT AS $$
BEGIN
    RETURN '2' || RIGHT(old_group, LENGTH(old_group) - 1);
END;
$$ LANGUAGE plpgsql;

Étape 2 : utiliser la fonction dans UPDATE

On met à jour le groupe de tous les étudiants :

UPDATE students
SET group_name = promote_student(group_name);

Résultat :

id name group_name
1 Otto 201
2 Anna 202
3 Alex 203

Regarde comment la fonction fait la magie de la mise à jour : les anciens groupes sont transformés en nouvelles valeurs.

Appeler des fonctions dans les conditions WHERE

Les fonctions peuvent être utilisées dans les conditions de filtrage. On va reprendre notre exemple avec l'âge des étudiants.

Étape 1 : filtrer par âge

On utilise la fonction calculate_age pour sélectionner les étudiants de plus de 20 ans :

SELECT id, name, birth_date
FROM students
WHERE calculate_age(birth_date) > 20;

Résultat :

id name birth_date
2 Anna 1998-05-15
3 Alex 1999-11-09

Ici, c'est la fonction qui fait tout le taf : elle calcule l'âge de chaque étudiant à la volée.

Combiner avec des fonctions d'agrégation

On va corser un peu. On veut compter le nombre total d'étudiants de moins de 22 ans. Les fonctions marchent super bien avec les fonctions d'agrégation comme COUNT().

SELECT COUNT(*)
FROM students
WHERE calculate_age(birth_date) < 22;

Qu'est-ce qui se passe ?

  • La fonction calculate_age est utilisée dans le filtre.
  • COUNT(*) compte le nombre de lignes qui matchent la condition.

Exemples concrets d'utilisation

Automatiser la validation des données. Imaginons que tu veux vérifier que l'âge de tous les étudiants de la table est dans une plage classique (genre de 18 à 30 ans). Écris une fonction de vérif et utilise-la dans la condition WHERE.

SELECT id, name
FROM students
WHERE NOT (calculate_age(birth_date) BETWEEN 18 AND 30);

Optimiser l'insertion des données. Imagine que tu bosses pour un e-shop. Plutôt que de calculer le prix total de la commande côté client, écris une fonction qui le calcule direct lors de l'ajout dans la table orders.

INSERT INTO orders (user_id, total_price)
VALUES (1, calculate_total_price(ARRAY[5, 10, 15]));

Erreurs courantes lors de l'appel de fonctions

Quand tu commences à utiliser les fonctions dans tes requêtes, tu peux tomber sur des erreurs. Voilà quelques cas classiques et comment les régler :

Manque de droits nécessaires. Si t'es pas proprio de la fonction ou de la table, PostgreSQL peut refuser l'appel. Vérifie que t'as les droits pour exécuter la fonction.

Problème de types. Quand tu passes des arguments à une fonction, fais gaffe aux types de données. Par exemple, si la fonction attend un DATE et que tu passes une chaîne, tu vas avoir une erreur. Utilise un cast explicite :

SELECT calculate_age('2000-01-01'::DATE);

Erreurs de syntaxe dans les fonctions. Si la fonction renvoie une erreur, ça peut planter toute la requête. Teste bien tes fonctions avant de les utiliser.

2
Mission
SQL SELF, niveau 50, leçon 2
Bloqué
Appel d'une fonction dans INSERT
Appel d'une fonction dans INSERT
Commentaires
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION