Lorsque des structures de base complexes sont créées qui 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.
ou en français :
DROP TABLE produits; NOTICE: la contrainte commandes_no_produit_fkey sur la table commandes dépend de la table produits ERREUR: la table produits ne peut pas être supprimée, car d'autres objets en dépendent HINT: Utiliser DROP ... CASCADE pour supprimer également les objets dépendants.
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.
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, 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 37.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.