Documentation PostgreSQL 14.22 » Langage SQL » Définition des données » Gestion des dépendances

Précédent | Niveau supérieur | Suivant
5.13. Autres objets de la base de données | Sommaire | Chapitre 6. Manipulation de données

## 5.14. Gestion des dépendances

Lorsque des structures de base complexes sont créées et qu'ils impliquent beaucoup de tables avec des contraintes de clés étrangères, des vues, des triggers, des fonctions, etc., un réseau de dépendances entre les objets est implicitement créé. Par exemple, une table avec une contrainte de clé étrangère dépend de la table à laquelle elle fait référence.

Pour garantir l'intégrité de la structure entière de la base, PostgreSQL s'assure qu'un objet dont d'autres objets dépendent ne peut pas être supprimé. Ainsi, toute tentative de suppression de la table des produits utilisée dans la Section 5.4.5, sachant que la table des commandes en dépend, lève un message d'erreur comme celui-ci :

    DROP TABLE produits;

    ERROR:  cannot drop table produits because other objects depend on it
    DETAIL:  constraint commandes_no_produit_fkey on table commandes depends on table produits
    HINT:  Use DROP ... CASCADE to drop the dependent objects too.

Le message d'erreur contient un indice utile : pour ne pas avoir à supprimer individuellement chaque objet dépendant, on peut lancer

    DROP TABLE produits CASCADE;

et tous les objets dépendants sont ainsi effacés, comme tous les objets dépendant de ces derniers, récursivement. Dans ce cas, la table des commandes n'est pas supprimée, mais seulement la contrainte de clé étrangère. Elle s'arrête là, car rien ne dépend d'une contrainte de clé étrangère. (Pour vérifier ce que fait `DROP ... CASCADE`, on peut lancer `DROP` sans `CASCADE` et lire les messages `DETAIL`.)

Pratiquement toutes les commandes `DROP` dans PostgreSQL supportent l'utilisation de `CASCADE`. La nature des dépendances est évidemment fonction de la nature des objets. On peut aussi écrire `RESTRICT` au lieu de `CASCADE` pour obtenir le comportement par défaut, à savoir interdire les suppressions d'objets dont dépendent d'autres objets.

### Note

D'après le standard SQL, il est nécessaire d'indiquer `RESTRICT` ou `CASCADE` dans une commande `DROP`. Aucun système de base de données ne force cette règle, en réalité, mais le choix du comportement par défaut, `RESTRICT` ou `CASCADE`, varie suivant le système.

Si une commande `DROP` liste plusieurs objets, `CASCADE` est seulement requis quand il existe des dépendances en dehors du groupe spécifié. Par exemple, en indiquant `DROP TABLE tab1, tab2`, l'existence d'une clé étrangère référençant `tab1` à partir de `tab2` ne signifie pas que `CASCADE` est nécessaire pour réussir.

Pour les fonctions définies par les utilisateurs ou les procédures dont le corps est défini comme une chaîne, PostgreSQL trace les dépendances associées avec les propriétés de la fonction visibles en externe, comme les types de données des arguments et du résultat. Par contre, il ne trace pas les dépendances seulement connues en examinant le corps de la fonction. Par exemple :

    CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow',
                                 'green', 'blue', 'purple');

    CREATE TABLE my_colors (color rainbow, note text);

    CREATE FUNCTION get_color_note (rainbow) RETURNS text AS
      'SELECT note FROM my_colors WHERE color = $1'
      LANGUAGE SQL;

(Voir Section 38.5 pour une explication sur les fonctions en SQL.) PostgreSQL aura connaissance du fait que la fonction `get_color_note` dépend du type `rainbow` : supprimer ce type de données forcera la suppression de la fonction parce que le type de son argument ne serait plus défini. Mais PostgreSQL ne considérera pas que la fonction `get_color_note` dépende de la table `my_colors`, et donc ne supprimera pas la fonction si la table est supprimée. Bien qu'il y ait des inconvénients à cette approche, il y a aussi des avantages. La fonction est toujours valide d'une certaine façon si la table est manquante, bien que son exécution causera une erreur. Créer une nouvelle table de même nom permettra à la fonction d'être valide de nouveau.

D'un autre côté, pour une fonction en langage SQL ou une procédure dont le corps est écrit dans un style SQL, le corps est analysé à la création de la fonction et toutes les dépendances reconnues par l'analyseur sont enregistrées. De ce fait, si nous écrivons la fonction ci-dessus ainsi :

    CREATE FUNCTION get_color_note (rainbow) RETURNS text
    BEGIN ATOMIC
      SELECT note FROM my_colors WHERE color = $1;
    END;

alors la dépendance de la fonction avec la table `my_colors` sera connu et respecté par une instruction `DROP`.