Précédent   Forum des professionnels en informatique > Bases de données > Langage SQL
Langage SQL Forum d'entraide sur le langage SQL et sur les questions liées à la conception de schéma (DDL). Cours SQL
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 27/01/2011, 09h26   #1
Invité de passage
 
Inscription : mai 2010
Messages : 24
Détails du profil
Informations forums :
Inscription : mai 2010
Messages : 24
Points : 1
Points : 1
Par défaut Problème clé étrangère clé primaire sur plusieurs tables.

Bonjour à tous,

Je me tourne vers vous après plus de 2h de recherche ne sachant plus trop quoi faire, je vous explique mon problème.

J'ai une table Contact :

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
CREATE TABLE IF NOT EXISTS `contact` (
  `idContact` int(10) UNSIGNED NOT NULL AUTO_INCREMENT,
  `lastname` varchar(255) DEFAULT NULL,
  `firstname` varchar(255) DEFAULT NULL,
  `adresse` varchar(255) DEFAULT NULL,
  `code_postal` varchar(255) DEFAULT NULL,
  `ville` varchar(255) DEFAULT NULL,
  `email` varchar(255) DEFAULT NULL,
  `idProfession` int(10) UNSIGNED DEFAULT NULL,
  `numero_etudiant` varchar(255) DEFAULT NULL,
  `lieu_exercice` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`idContact`),
  KEY `contact_FKIndex1` (`idProfession`)
) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=9 ;

J'ai ensuite une table option qui est liée à contact avec un ON DELETE CASCADE pour que si un contact est supprimé les champs de la table option soient supprimés aussi.
Voici la structure de ma table option :

Code :
1
2
3
4
5
6
7
8
CREATE TABLE IF NOT EXISTS `options` (
         `id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT,
	 `idTable` int(10) UNSIGNED NOT NULL,
	 `idContact` int(10) UNSIGNED DEFAULT NULL,
	 `nomTable` varchar(50), 
	 PRIMARY KEY(`idTable`),
	 FOREIGN KEY(`idContact`) REFERENCES contact(`idContact`) ON DELETE CASCADE
	 )ENGINE=INNODB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=0
Pour simplifier l'explication voici un screen de ma table options peuplée :


L'attribut `idTable` est valorisé quand j'insert le choix dans la table qui représentée par nomTable je récupère la dernière insertion et la met à la place de idTable.

Voici un exemple de table de choix (Gala_ChampOptionnel0).



Je vous explique maintenant ce que je veux faire : quand un contact est supprimé les champs de la table options correspondants au contact sont supprimés et les lignes des champs optionnels contenant les choix des options supprimés doivent l'être aussi. En gros tout ce qui a rapport avec un contact supprimé doit l'être aussi.

Pour supprimé les champs de options si un contact est supprimé avec un ON DELETE CASCADE cela se fait très bien le problème vient quand je veux il faut supprimer les champs des tables de choix (comme Gala_ChampOptionnel0) car la clé primaire de ma table est l'option est un id et je valorise le champ idTable une fois l'insertion faite dans ma table de choix. Hors pour faire un ON DELETE CASCADE sur une clé étrangère il faut que celle ci soit l'UNIQUE clé primaire de la table ce qui n'est pas le cas.

Si vous n'avez pas compris je peux ré expliquer le problème est un peu lourd à comprendre et je m'en excuse. Toute idée est la bienvenue!
ABonus est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 27/01/2011, 10h12   #2
rsc
Membre émérite
 
Avatar de rsc
 
Homme
Développeur informatique
Inscription : juin 2004
Messages : 697
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 61
Localisation : France, Côte d'Or (Bourgogne)

Informations professionnelles :
Activité : Développeur informatique
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : juin 2004
Messages : 697
Points : 871
Points : 871
Citation:
Envoyé par ABonus Voir le message
Si vous n'avez pas compris je peux ré expliquer le problème est un peu lourd à comprendre et je m'en excuse. Toute idée est la bienvenue!
Effectivement, je n'ai pas tout compris. Au moins 3 questions :

1/ D'après ton script de création de table, la clé primaire de Options est id_table, hors dans ton screen, on voit des valeurs de id_table en double

2/ Tu n'expliques pas à quoi sert ta table GalaChampOptionnel, ni ce que représente la colonne "choix"

3/
Citation:
Envoyé par ABonus Voir le message
Hors pour faire un ON DELETE CASCADE sur une clé étrangère il faut que celle ci soit l'UNIQUE clé primaire de la table ce qui n'est pas le cas.
Parce que dans une table, il peut y avoir deux clés primaires ?? Il va falloir que je revoie ma définition de "primaire"
__________________
Roland
rsc est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 27/01/2011, 10h37   #3
Invité de passage
 
Inscription : mai 2010
Messages : 24
Détails du profil
Informations forums :
Inscription : mai 2010
Messages : 24
Points : 1
Points : 1
J'ai corrigé la structure de ma table option je pense que se sera plus compréhensible.

Citation:
2/ Tu n'expliques pas à quoi sert ta table GalaChampOptionnel, ni ce que représente la colonne "choix"
Cette table contient en fait un choix du contact pour un champ dans un formulaire qui s'appellera GalaChampOptionnel (je ne peux pas te décrire toute ma structure se serait trop long) Mais j'ai des objet GalaChampOptionnel qui me permettent de calculer le prix en fonction du choix de l'utilisateur qui est entré dans la base de données via cette table.

Un table peut avoir pour clé primaire 2 clés étrangères il me semble. Après je ne sais pas si je peux lui donner 2 clé primaire (l'une étrangère et l'autre pas).
ABonus est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 27/01/2011, 10h56   #4
rsc
Membre émérite
 
Avatar de rsc
 
Homme
Développeur informatique
Inscription : juin 2004
Messages : 697
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 61
Localisation : France, Côte d'Or (Bourgogne)

Informations professionnelles :
Activité : Développeur informatique
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : juin 2004
Messages : 697
Points : 871
Points : 871
Citation:
Envoyé par ABonus Voir le message
Un table peut avoir pour clé primaire 2 clés étrangères il me semble. Après je ne sais pas si je peux lui donner 2 clé primaire (l'une étrangère et l'autre pas).
Une table ne peut avoir qu'une clé primaire. Par contre, une clé primaire peut avoir plusieurs colonnes. Chacune de ces colonnes peut être ou ne pas être une clé étrangère.
Les conditions sont que :
- ces colonnes ne contiennent pas de valeurs Null
- il n'existe pas dans la table deux lignes qui aient, pour ces colonnes, le même ensemble de valeurs.

Donc :
- Quelle est la clé primaire de GalaChampOptionnel (de quelle(s) colonne(s) est-elle constituée) ?
- Ces colonnes sont-elles des clés étrangères ? A quoi se réfèrent-elles ?
- Y a-t-il d'autres clés étrangères dans la table ?

Quand on saura tout ça je pense qu'on comprendra pourquoi tes suppressions échouent.
__________________
Roland
rsc est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 27/01/2011, 11h06   #5
Invité de passage
 
Inscription : mai 2010
Messages : 24
Détails du profil
Informations forums :
Inscription : mai 2010
Messages : 24
Points : 1
Points : 1
La clé primaire de galaChampOptionnel est id, ces colonnes ne sont pas clés étrangères. Non il n'y a pas d'autre clé étrangère dans la table.
En fait je voudrais que l'id (de la table GalaChampOptionnel) fasse référence à la clé idTable. Néanmoins le problème étant que je génère idTable en fonction de l'id de galaChampOptionnel...
ABonus est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 27/01/2011, 11h31   #6
rsc
Membre émérite
 
Avatar de rsc
 
Homme
Développeur informatique
Inscription : juin 2004
Messages : 697
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 61
Localisation : France, Côte d'Or (Bourgogne)

Informations professionnelles :
Activité : Développeur informatique
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : juin 2004
Messages : 697
Points : 871
Points : 871
Evidemment, tu ne peux pas mettre de clé étrangère puisque la ligne de Gala.. est créée avant qu' id_table soit renseignée. A la limite, tu pourrais mettre une clé étrangère dans l'autre sens (id_table reference id), mais elle ne t'aidera pas à supprimer "automatiquement" ta ligne.

En fait, si je comprends bien, Chaque ligne dans Gala correspond à une seule ligne d'Options ?

Si c'est le cas, la solution est de laisser tomber la colonne id_table dans Options, et d'ajouter une colonne id_option dans Gala.. qui référence l'identifiant de la table options.

(A ce propos, je te conseille de donner des noms spécifiques aux colonnes d'identifiants de tes tables (id_option pour Options, etc...) c'est plus clair, les relations d'intégrité référentielles se font entre colonnes de même nom)


Ensuite, avec un DELETE CASCADE, lorsque tu supprimes la ligne d'Options, la ligne correspondant de Gala est supprimée.
__________________
Roland
rsc est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 27/01/2011, 11h42   #7
Invité de passage
 
Inscription : mai 2010
Messages : 24
Détails du profil
Informations forums :
Inscription : mai 2010
Messages : 24
Points : 1
Points : 1
Effectivement chaque ligne dans Gala correspond à une seule ligne d'Options.

Oui ta solution me semble la meilleur dans le sens ou cela ne me fait pas trop de changement dans mon système actuel.
ABonus est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 27/01/2011, 11h52   #8
rsc
Membre émérite
 
Avatar de rsc
 
Homme
Développeur informatique
Inscription : juin 2004
Messages : 697
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 61
Localisation : France, Côte d'Or (Bourgogne)

Informations professionnelles :
Activité : Développeur informatique
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : juin 2004
Messages : 697
Points : 871
Points : 871
Je suis content que ça te convienne .

Bon courage

NB : Si c'est résolu, n'oublie de mettre la balise au fil de discussion, c'est sympa pour ceux qui parcourent les fils pour aider !
__________________
Roland
rsc est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 27/01/2011, 11h54   #9
Invité de passage
 
Inscription : mai 2010
Messages : 24
Détails du profil
Informations forums :
Inscription : mai 2010
Messages : 24
Points : 1
Points : 1
Je mettrais résolu et ma solution. Merci pour ton aide! : )
ABonus est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 27/01/2011, 14h53   #10
Invité de passage
 
Inscription : mai 2010
Messages : 24
Détails du profil
Informations forums :
Inscription : mai 2010
Messages : 24
Points : 1
Points : 1
Voila pour ceux qui sont interessés voici la structure de mes trois tables (qui fonctionne ! )

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
CREATE TABLE IF NOT EXISTS contact (
	  idContact int(10) UNSIGNED NOT NULL AUTO_INCREMENT,
	  lastname varchar(255) DEFAULT NULL,
	  firstname varchar(255) DEFAULT NULL,
	  adresse varchar(255) DEFAULT NULL,
	  code_postal varchar(255) DEFAULT NULL,
	  ville varchar(255) DEFAULT NULL,
	  email varchar(255) DEFAULT NULL,
	  idProfession int(10) UNSIGNED DEFAULT NULL,
	  numero_etudiant varchar(255) DEFAULT NULL,
	  lieu_exercice varchar(255) DEFAULT NULL,
	  PRIMARY KEY (idContact),
	  KEY contact_FKIndex1 (idProfession)
	) ENGINE=INNODB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=0;
 
 
 
CREATE TABLE IF NOT EXISTS options (
	idOption int(10) UNSIGNED NOT NULL AUTO_INCREMENT,
	idContact int(10) UNSIGNED NOT NULL,
	nomTable varchar(50) DEFAULT NULL,
	 PRIMARY KEY(idOption),
	 FOREIGN KEY(idContact) REFERENCES contact(idContact) ON DELETE CASCADE
	 )ENGINE=INNODB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=0
 
 
CREATE TABLE gala(
     idGala int(10) UNSIGNED NOT NULL AUTO_INCREMENT,
	 choix varchar(50),
	 idOption int(10)UNSIGNED NOT NULL,
	 PRIMARY KEY(idGala),
	 FOREIGN KEY(idOption) REFERENCES options(idOption) ON DELETE CASCADE
	 )ENGINE=INNODB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=0
ABonus est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité Cette discussion est résolue.
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 04h50.


 
 
 
 
Partenaires

Hébergement Web