Précédent   Forum des professionnels en informatique > Bases de données > MySQL > SQL Procédural
SQL Procédural Forum d'entraide sur les triggers, les procédures stockées et les fonctions en MySQL
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 13/02/2008, 19h19   #1
Membre du Club
 
Inscription : août 2007
Messages : 141
Détails du profil
Informations forums :
Inscription : août 2007
Messages : 141
Points : 62
Points : 62
Par défaut Clés etrangères sous MySQL

Bonsoir,

je pose une question qui revient peut etre souvent mais malgre qq recherches je n ai pas vraiment trouvé de reponses satisfaisantes.

Voila, je vous expose ma problematique qui est assez simple et assez souvent vu :

creation de plusieurs tables en cascade facon arborescence et je voudrais y inclure un champ qui indique si un user verrouille le repertoire, donc cela veut dire qu a la creation du repertoire le user n est pas renseigné....ce qui se fera plus tard.

J'ai donc crée une clé etrangere sur le champ de ce style :

Code :
1
2
 
CONSTRAINT `fkOwner` FOREIGN KEY (`OWNER`) REFERENCES `dbusers` (`ID`) avec ID cle primaine de ma TABLE dbusers
et mon champ OWNER est definit de la sorte sachant que je definis toutes mes cles primaires de table en bigint unsigned not null :

Code :
1
2
 
  `OWNER` bigint(20) UNSIGNED DEFAULT NULL COMMENT 'Index user'
j'ai mis NULL pour l insertion non renseignée du départ.


Pourtant cela ne semble pas fonctionner.
Il n'est pas possible de créer une cle etrangere sur un champ non renseigné à l'insertion ? ou dois je mettre NOT NULL default 0 ?
ou devons nous modifier les options de "mise à jour" a SET NULL par exemple au lieu de RESTRICT ?

Bref si qqun peut me filer un tuyau.
Un grand merci d avance.

A+
Targan est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 13/02/2008, 20h51   #2
Rédacteur/Modérateur

 
Avatar de Antoun
 
Homme Antoine Dinimant
Consultant en Business Intelligence
Inscription : octobre 2006
Messages : 5 854
Détails du profil
Informations personnelles :
Nom : Homme Antoine Dinimant
Âge : 42
Localisation : France, Paris (Île de France)

Informations professionnelles :
Activité : Consultant en Business Intelligence
Secteur : Conseil

Informations forums :
Inscription : octobre 2006
Messages : 5 854
Points : 9 540
Points : 9 540
Pour que ça fonctionne, il faut que tes deux tables soient en InnoDB...

Tu peux par exemple faire un SHOW CREATE TABLE sur chacune ; à la fin du CREATE, tu dois avoir la clause ENGINE = qui te donne le moteur de stockage. Si ce n'est pas InnoDB, tu peut le modifier ainsi :

Code SQL :
ALTER TABLE machin ENGINE = InnoDB ;
__________________
Antoun
Expert SQL, BO, Essbase

La bible d'Essbase est parue !
Antoun est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 13/02/2008, 21h37   #3
Membre du Club
 
Inscription : août 2007
Messages : 141
Détails du profil
Informations forums :
Inscription : août 2007
Messages : 141
Points : 62
Points : 62
merci pour ta reponse.

Mais elles sont bien en innodb, d ailleurs jai besoin des transactions....


Des que j'insere un enregistrement j'ai droit a une erreur parent/child sur la contrainte d integrite.
Targan est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 13/02/2008, 23h19   #4
Rédacteur/Modérateur

 
Avatar de Antoun
 
Homme Antoine Dinimant
Consultant en Business Intelligence
Inscription : octobre 2006
Messages : 5 854
Détails du profil
Informations personnelles :
Nom : Homme Antoine Dinimant
Âge : 42
Localisation : France, Paris (Île de France)

Informations professionnelles :
Activité : Consultant en Business Intelligence
Secteur : Conseil

Informations forums :
Inscription : octobre 2006
Messages : 5 854
Points : 9 540
Points : 9 540
Pourrais montrer le CREATE TABLE complet de deux de tes tables liées par une intégrité référentielle, ainsi que la requête qui provoque une erreur ?
__________________
Antoun
Expert SQL, BO, Essbase

La bible d'Essbase est parue !
Antoun est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 14/02/2008, 09h16   #5
Membre du Club
 
Inscription : août 2007
Messages : 141
Détails du profil
Informations forums :
Inscription : août 2007
Messages : 141
Points : 62
Points : 62
Code :
1
2
3
4
5
6
7
8
9
10
11
12
 
CREATE TABLE `Users` (
  `ID` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT,
  `dbLOGIN` varchar(50) NOT NULL COMMENT 'Login utilisateur',
  `dbNAME` varchar(100) NOT NULL COMMENT 'Nom de l utilisateur',
  `dbPASSWORD` varchar(50) DEFAULT NULL COMMENT 'Password crypte',
  `dbRIGHTS` tinyint(4) UNSIGNED NOT NULL DEFAULT '0' COMMENT 'Droits utilisateur',
  `dbACTIVATED` tinyint(1) NOT NULL DEFAULT '0' COMMENT 'Indique si l utilisateur est actif ou non',
  PRIMARY KEY  (`ID`),
  UNIQUE KEY `idxLogin` (`dbLOGIN`),
  KEY `idxGetActivatedUser` (`dbACTIVATED`,`dbLOGIN`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=latin1 COMMENT='Liste des utilisateurs';
Et voici ma table dans laquelle j ai ma cle etrangere qui me bloque à l'ajout d'une donnée :

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
 
CREATE TABLE `dbChildDirectory` (
  `ID` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT,
  `dbIDDIR` bigint(20) UNSIGNED NOT NULL COMMENT 'Index de repertoire parent',
  `dbDATECREATE` datetime NOT NULL COMMENT 'Date de creation',
  `dbUSERCREATE` bigint(20) UNSIGNED NOT NULL COMMENT 'Utilisateur a l origine du repertoire',
  `dbPATH` varchar(255) NOT NULL COMMENT 'Path relatif',
  `dbXML` mediumblob NOT NULL COMMENT 'Fichier XML descriptif',
  `dbOWNER` bigint(20) UNSIGNED DEFAULT NULL COMMENT 'Utilisateur qui a verrouille le repertoire',
  PRIMARY KEY  (`ID`),
  UNIQUE KEY `idxGetDir` (`dbIDDIR`,`dbPATH`),
  KEY `idxdbIDDIR` (`dbIDDIR`),
  KEY `idxdbUSERCREATE` (`dbUSERCREATE`),
  KEY `idxdbOWNER` (`dbOWNER`),
  CONSTRAINT `fkDIROwner` FOREIGN KEY (`dbOWNER`) REFERENCES `Users` (`ID`),
  CONSTRAINT `fkDIRPresta` FOREIGN KEY (`dbIDDIR`) REFERENCES `dbParentDirectory` (`ID`),
  CONSTRAINT `fkDIRUserCreate` FOREIGN KEY (`dbUSERCREATE`) REFERENCES `Users` (`ID`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=latin1 COMMENT='Liste des sous repertoires';
et c'est cette contrainte qui bloque : CONSTRAINT `fkDIROwner` FOREIGN KEY (`dbOWNER`) REFERENCES `Users` (`ID`),
Targan est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 14/02/2008, 10h04   #6
Expert Confirmé Sénior
 
Avatar de qi130
 
Homme Pierre
Ingénieur qualité méthodes
Inscription : mars 2003
Messages : 3 726
Détails du profil
Informations personnelles :
Nom : Homme Pierre
Âge : 51
Localisation : France

Informations professionnelles :
Activité : Ingénieur qualité méthodes
Secteur : Finance

Informations forums :
Inscription : mars 2003
Messages : 3 726
Points : 4 739
Points : 4 739
Si tu ne renseignes pas cette colonne
Code :
`dbOWNER` bigint(20) UNSIGNED DEFAULT NULL
le SGBD tente d'y mettre NULL et recherche un FK ayant cette valeur...

Et je doute qu'il la trouve dans la tables users, puisque cette colonne est en auto incrément (donc toujours <>NULL).

Il faut donc utiliser le last_insert_id pour alimenter dbOWNER
__________________
"Il n'y a pas de bonnes réponses à une mauvaise question." (M. Godet)
-----------------------
Pensez à cloturer votre sujet - Aucune réponse aux sollicitations techniques par MP
Usus magister est optimus
qi130 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 14/02/2008, 10h59   #7
Membre du Club
 
Inscription : août 2007
Messages : 141
Détails du profil
Informations forums :
Inscription : août 2007
Messages : 141
Points : 62
Points : 62
Ok, je comprends mieux le pb....

Maintenant, comment faire pour ne pas devoir renseigner la valeur Owner de suite mais le faire plus tard ?
On ne doit tout de meme pas supprimer la cle etrangere ?

Doit bien exister un moyen de mettre une valeur qui n'est pas dans la table user car je vois qu il y a 2 "triggers" sur les cles etrangeres qui permettent de modifier les valeurs qd y a suppression et mise à jour avec une commande SET NULL à la place de RESTRICT ?

Peut etre devrais mettre SET NULL pour les mises à jour sur cette cle etrangere ?


Merci pour votre aide en tout cas.
Targan est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 14/02/2008, 22h02   #8
Expert Confirmé Sénior
 
Avatar de qi130
 
Homme Pierre
Ingénieur qualité méthodes
Inscription : mars 2003
Messages : 3 726
Détails du profil
Informations personnelles :
Nom : Homme Pierre
Âge : 51
Localisation : France

Informations professionnelles :
Activité : Ingénieur qualité méthodes
Secteur : Finance

Informations forums :
Inscription : mars 2003
Messages : 3 726
Points : 4 739
Points : 4 739
Si tu souhaites laisser la contrainte en place, je ne vois que 2 solutions:
1/ soit tu récupères l'id de la FK
2/ soit tu "bricoles" ton modèle afin que la contrainte soit satisfaite: 1 ligne avec valeur de l'ID à NULL (mais pb à l'horizon rapport à l'auto-incrément)

Si tu veux te passer de la contrainte gérée par le SGBD, l'effort de cohésion/cohérence de ta base sera à ta charge...

En définitive, même si ce n'est pas élégant (et peut-être pas portable):
Citation:
InnoDB does not check foreign key constraints on those foreign key or referenced key values that contain a NULL column.
__________________
"Il n'y a pas de bonnes réponses à une mauvaise question." (M. Godet)
-----------------------
Pensez à cloturer votre sujet - Aucune réponse aux sollicitations techniques par MP
Usus magister est optimus
qi130 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 15/02/2008, 00h27   #9
Membre du Club
 
Inscription : août 2007
Messages : 141
Détails du profil
Informations forums :
Inscription : août 2007
Messages : 141
Points : 62
Points : 62
Bon alors la je ne comprends pas du tout.

Sur une autre table j ai fait la meme chose, cest a dire que j ai mis default null sur la colonne sur laquelle est definie la cle etrangere et je peux parfaitement inserer des données sans que ca coince.

Mais sur cette table, pourtant identique sur le fonctionnement, il y a un soucy....

Est ce que cela ne viendra pas d'EMS MySQL (version 2005) par hasard ? cest avec lui que j ai cree mes contraintes.
Targan est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 19h06.


 
 
 
 
Partenaires

Hébergement Web