Salut tout le monde. Est ce qu'il y a une solution pour que je puisse changer une clé primaire qui est une clé étrangère dans une table. Exple: je voudrai changer le matricule d'un client et que le matricule change dans la table commande ????
Salut tout le monde. Est ce qu'il y a une solution pour que je puisse changer une clé primaire qui est une clé étrangère dans une table. Exple: je voudrai changer le matricule d'un client et que le matricule change dans la table commande ????
Avez-vous défini une contrainte d'intégrité référentielle entre les tables CLient et Commande ?je voudrai changer le matricule d'un client et que le matricule change dans la table commande
oui, j'ai mit dans la table commande (matricule) comme clé étrangère. c'est cette contrainte qui bloque la modification. je l'ai désactivé pour changer le matricule et bein ça ne se fait que dans la table client et non pas dans la table commande
L’objet de l’intégrité référentielle est de faire en sorte qu’on ne puisse pas se retrouver avec une commande sans client associé. Le fait de débrancher la contrainte référentielle fait ... qu’il n’y a plus de contrainte, donc que l’on puisse modifier la clé du client sans répercussion dans la table commande : c’est particulièrement redoutable.
Il faut donc conserver la contrainte référentielle, mais modifier le trigger qui lui est associé.
Supposons que vous ayez codé :
En l’état, la contrainte C3 interdit la modification de la clé primaire de la table Client s’il existe une commande faisant référence au client associé.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14 Create Table Client ( Matricule Integer ... ... , Constraint C1 Primary Key (Matricule) ... ) ; Create Table Commande ( CommandeId Integer ... , Matricule Integer ... ... , Constraint C2 Primary Key (CommandeId) ... , Constraint C3 Foreign Key (Matricule) References Client ... ) ;
Pour propager la modification dans la table Commande, il faut modifier la contrainte C3 :
Étant sous-entendu que votre SGBD permette de le coder.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 Constraint C3 Foreign Key (Matricule) References Client On Update Cascade
Si le SGBD ne permet pas la modification des clés en cascade, il faut trouver une alternative (cas par exemple de DB2 et d'Oracle).
Pour reprendre mon exemple, on peut supprimer la contrainte C3 et garantir l’intégrité référentielle par un trigger, mais attention à bien prendre en compte tous les cas de figure qui peuvent se présenter :
Rattachement d’une commande à un client existant, changement de rattachement, suppression d’un client, remplacement de la valeur de la clé primaire du client (le cas qui vous préoccupe...)
Sinon, vous pouvez procéder ainsi :
Soit C1 le client dont on veut modifier le matricule valant "m1" et devant prendre la valeur "m2" :
Insert d’un client C2 identique à C1, mais avec le matricule "m2".
Update des commandes de C1, en y remplaçant "m1 par "m2".
Delete du client C1.
Évidemment, si cela se produit souvent, c’est un peu lourd...
Moralité : éviter de prendre comme clé primaire un attribut susceptible de varier dans le temps. A l’avenir, pour la clé primaire, définissez un attribut ad-hoc, invariant et ravalez Matricule au rang de clé alternative.
=> Autrement dit, vous avez une autre solution :
Ajouter à la table Client une colonne invariante ClientId.
Vous recopiez dans cette colonne la colonne Matricule : à cet instant, les deux colonnes font double emploi.
Ensuite :
Alter Table Commande : DROP de la contrainte FOREIGN KEY actuelle (Matricule)
Alter Table Commande : renommer la colonne Matricule en ClientId (c’est facultatif, mais plus propre).
Alter Table Client : DROP de la contrainte PRIMARY KEY (Matricule)
Alter Table Client : ADD d’une nouvelle contrainte UNIQUE (Matricule)
Alter Table Client : ADD de la contrainte PRIMARY KEY (ClientId)
Alter Table Commande : ADD de la contrainte FOREIGN KEY nouvelle (ClientId).
Les valeurs de la colonne ClientId de la table Commande sont valides, puisque pour le moment les colonnes Matricule et ClientId de la table Client font double emploi.
Sous réserve que je n’ai rien oublié (je ne traite pas par exemple des index et autres concepts physiques), à partir de maintenant on peut modifier un matricule, mais sous réserve bien sûr de ne pas modifier ClientId qui par définition est invariant (et du reste n’a pas à être montré à l’utilisateur, qui ne voit que Matricule). Désormais, les deux colonnes ClientId et Matricule ne font plus double emploi.
ok, je vais essayer mais c'est compliqué Merci beaucoup.![]()
Vous avez un bloqueur de publicités installé.
Le Club Developpez.com n'affiche que des publicités IT, discrètes et non intrusives.
Afin que nous puissions continuer à vous fournir gratuitement du contenu de qualité, merci de nous soutenir en désactivant votre bloqueur de publicités sur Developpez.com.
Partager