aucune correspondance entre deux tables

Répondre


Cette question est un moyen d’empêcher des soumissions automatisées de formulaires par des robots.
Smileys
:D :) :( :o :shock: :? 8-) :lol: :x :P :oops: :cry: :evil: :twisted: :roll: :wink: :!: :?: :idea: :arrow: :| :mrgreen: =D> #-o =P~ :^o :non: :priere: 8-|
Voir plus de smileys
  Revue du sujet
 

  Étendre la vue Revue du sujet : aucune correspondance entre deux tables

par sadeq » 10 déc. 2008, 17:30

Si tu ne veux pas que la contrainte relationnelle t'empêche de modifier ou supprimer des champs liées (clé étrangère/clé primaire) il faut autoriser les modifications et suppressions en cascade dans la définition de la relation. La solution n'est pas de remettre en cause le rôle des clés étrangères qui assurent le lien entre les tables. Si tu remets en cause un tel concept, pourquoi alors opter pour l'usage d'une base de données relationnelle.

Voici comment activer les modifications et suppressions en cascade sur une relation entre deux tables.
Je rappelle pour cela que la relation est définie dans la table qui contient la clé étrangère et qui pointe vers la clé primaire de la table liée. Voici donc comment :

Soit les 2 tables de l'exemple :
  • Table: client (id, nom) et Table: commande (numero, date, id_client)
    La clé primaire de la table client est le champ (id) et celle de la table commande est le champ (numero)
    La clé étrangère est le champ (id_client) qui se trouve dans la table commande et qui n'est que le sosie ou la copie du champ (id) de la table client.
La clé étrangère (id_client) assure donc le lien entre un client et ses commandes pour éviter de devoir renseigner toutes les information du client quand on lui crée des commandes.

Voici, le code SQL pour déclarer les tables :

Code : Tout sélectionner

Create Table client( id int not null, nom varchar(20) not null, primary key (id) ); Create Table commande ( numero int not null, date datetime not null, id_client int not null, primary key (numero) );
Voici le code SQL pour définir la relation avec modifications et suppressions en cascade:

Code : Tout sélectionner

Alter Table commande Add Constraint 'fk_commande_client' Foreign Key (id_client) References client(id) ON Update Cascade ON Delete Cascade;
Par contre, si les tables et la relation sont déjà définies, on peut modifier la relation par exemple avec le code suivant (en spécifiant Alter au lieu de Add) :

Code : Tout sélectionner

Alter Table commande Alter Constraint 'fk_commande_client' Foreign Key (id_client) References client(id) ON Update Cascade ON Delete Cascade;

par Cypher_PHP » 10 déc. 2008, 16:00

franchement
j'ai du mal avec les clés étrangères

car je me heurte au pb de contrainte
Cannot add or update a child row: a foreign key constraint fails
je me suis renseigné auprès de Google.
je crois comprendre que quand on supprime ou ajoute, il faudrait d'abord supprimer ou ajouter dans la table fille pour pouvoir remplir ensuite la table mere..

mes tables sont l'une vides, l'autre remplies. pas évident de gérer .

donc je préfère supprimer les clés étrangères.


merci à vous

par furiouslol » 09 déc. 2008, 15:18

Ben la tu vois dans ta table sessions tu établi tes liaison avec les autres tables avec des strings au lieu d'utiliser les id de tes autres tables

Code : Tout sélectionner

`horaire_matin` VARCHAR(17) NOT NULL , `horaire_apres_midi` VARCHAR(17) NOT NULL , `salle` VARCHAR(10) NOT NULL , `places` VARCHAR(3) NOT NULL , `code` VARCHAR(10) NOT NULL ,
Si tu change le nom de la salle par exemple dans ta table salle, ta liaison va sauter, il faut que tu utilise id_salle en INT(3)

Tu peux créer les liaisons sans CONSTRAINT au début, les contraintes servent a protéger les liaison d'une modification ou d'un ajout non autorisé, mais la relation est utilisable sans, mais en tout cas il faut que tu créé tes liaison avec des clefs primaire (exemple id_salle), car tu est sur qu'elle ne seront pas modifiées dans la table de référence ( la table salle par exemple )

par Cypher_PHP » 09 déc. 2008, 11:55

ok
je vais modifier la structure pour ajouter la clé étrangère
je vous en dirai plus aujourd'hui

je voudrais solliciter vos avis sur mes structures qui me paraissent longs (excuse moi)
(il n'existe pas de pièces jointes??)

Code : Tout sélectionner

DROP DATABASE IF EXISTS `dbgestforma` ; CREATE SCHEMA IF NOT EXISTS `dbgestforma` DEFAULT CHARACTER SET latin1 COLLATE latin1_swedish_ci ; USE `dbgestforma`; -- ----------------------------------------------------- -- Table `dbgestforma`.`agent` -- ----------------------------------------------------- DROP TABLE IF EXISTS `dbgestforma`.`agent` ; CREATE TABLE IF NOT EXISTS `dbgestforma`.`agent` ( `id_agent` INT(3) NOT NULL AUTO_INCREMENT , `nom` VARCHAR(50) NOT NULL , `prenom` VARCHAR(50) NOT NULL , INDEX `id_agent` (`id_agent` ASC) , PRIMARY KEY (`id_agent`) ) ENGINE = InnoDB DEFAULT CHARACTER SET = latin1; -- ----------------------------------------------------- -- Table `dbgestforma`.`code` -- ----------------------------------------------------- DROP TABLE IF EXISTS `dbgestforma`.`code` ; CREATE TABLE IF NOT EXISTS `dbgestforma`.`code` ( `id_code` INT(5) NOT NULL AUTO_INCREMENT , `code` VARCHAR(10) NOT NULL , `nom` VARCHAR(50) NOT NULL , INDEX `id_code` (`id_code` ASC) , PRIMARY KEY (`id_code`) ) ENGINE = InnoDB DEFAULT CHARACTER SET = latin1; -- ----------------------------------------------------- -- Table `dbgestforma`.`horaire` -- ----------------------------------------------------- DROP TABLE IF EXISTS `dbgestforma`.`horaire` ; CREATE TABLE IF NOT EXISTS `dbgestforma`.`horaire` ( `id_horaire` INT(3) NOT NULL AUTO_INCREMENT , `matin` VARCHAR(15) NOT NULL , `apres_midi` VARCHAR(17) NOT NULL , INDEX `id_horaire` (`id_horaire` ASC) , PRIMARY KEY (`id_horaire`) ) ENGINE = InnoDB DEFAULT CHARACTER SET = latin1; -- ----------------------------------------------------- -- Table `dbgestforma`.`salle` -- ----------------------------------------------------- DROP TABLE IF EXISTS `dbgestforma`.`salle` ; CREATE TABLE IF NOT EXISTS `dbgestforma`.`salle` ( `id_salle` INT(3) NOT NULL AUTO_INCREMENT , `salle` VARCHAR(15) NOT NULL , `etage` VARCHAR(5) NOT NULL , `adresse` VARCHAR(50) NOT NULL , `adresse_bis` VARCHAR(50) NOT NULL , `code_postal` INT(6) NOT NULL , `ville` VARCHAR(25) NOT NULL , INDEX `id_salle` (`id_salle` ASC) , PRIMARY KEY (`id_salle`) ) ENGINE = InnoDB DEFAULT CHARACTER SET = latin1; -- ----------------------------------------------------- -- Table `dbgestforma`.`tuteur` -- ----------------------------------------------------- DROP TABLE IF EXISTS `dbgestforma`.`tuteur` ; CREATE TABLE IF NOT EXISTS `dbgestforma`.`tuteur` ( `id_tuteur` INT(3) NOT NULL AUTO_INCREMENT , `nom` VARCHAR(50) NOT NULL , `prenom` VARCHAR(50) NOT NULL , `agent_id_agent` INT(3) NOT NULL , INDEX `id_tuteur` (`id_tuteur` ASC) , PRIMARY KEY (`id_tuteur`, `agent_id_agent`) , INDEX `fk_tuteur_agent` (`agent_id_agent` ASC) , CONSTRAINT `fk_tuteur_agent` FOREIGN KEY (`agent_id_agent` ) REFERENCES `dbgestforma`.`agent` (`id_agent` ) ON DELETE NO ACTION ON UPDATE NO ACTION) ENGINE = InnoDB DEFAULT CHARACTER SET = latin1; -- ----------------------------------------------------- -- Table `dbgestforma`.`session` -- ----------------------------------------------------- DROP TABLE IF EXISTS `dbgestforma`.`session` ; CREATE TABLE IF NOT EXISTS `dbgestforma`.`session` ( `id_session` INT(3) NOT NULL AUTO_INCREMENT , `session` VARCHAR(25) NOT NULL , `intitule` VARCHAR(50) NOT NULL , `commentaires` TEXT NOT NULL , `nomcomplet` VARCHAR(50) NOT NULL , `horaire_matin` VARCHAR(17) NOT NULL , `horaire_apres_midi` VARCHAR(17) NOT NULL , `salle` VARCHAR(10) NOT NULL , `places` VARCHAR(3) NOT NULL , `code` VARCHAR(10) NOT NULL , `date_debut` VARCHAR(17) NOT NULL , `date_fin` VARCHAR(17) NOT NULL , `visible` CHAR(1) NULL DEFAULT NULL , `horaire_id_horaire` INT(3) NOT NULL , `agent_id_agent` INT(3) NOT NULL , `tuteur_id_tuteur` INT(3) NOT NULL , `salle_id_salle` INT(3) NOT NULL , `code_id_code` INT(5) NOT NULL , INDEX `id_session` (`id_session` ASC) , PRIMARY KEY (`horaire_id_horaire`, `agent_id_agent`, `tuteur_id_tuteur`, `salle_id_salle`, `code_id_code`) , INDEX `fk_session_horaire` (`horaire_id_horaire` ASC) , INDEX `fk_session_agent` (`agent_id_agent` ASC) , INDEX `fk_session_tuteur` (`tuteur_id_tuteur` ASC) , INDEX `fk_session_salle` (`salle_id_salle` ASC) , INDEX `fk_session_code` (`code_id_code` ASC) , CONSTRAINT `fk_session_horaire` FOREIGN KEY (`horaire_id_horaire` ) REFERENCES `dbgestforma`.`horaire` (`id_horaire` ) ON DELETE NO ACTION ON UPDATE NO ACTION, CONSTRAINT `fk_session_agent` FOREIGN KEY (`agent_id_agent` ) REFERENCES `dbgestforma`.`agent` (`id_agent` ) ON DELETE NO ACTION ON UPDATE NO ACTION, CONSTRAINT `fk_session_tuteur` FOREIGN KEY (`tuteur_id_tuteur` ) REFERENCES `dbgestforma`.`tuteur` (`id_tuteur` ) ON DELETE NO ACTION ON UPDATE NO ACTION, CONSTRAINT `fk_session_salle` FOREIGN KEY (`salle_id_salle` ) REFERENCES `dbgestforma`.`salle` (`id_salle` ) ON DELETE NO ACTION ON UPDATE NO ACTION, CONSTRAINT `fk_session_code` FOREIGN KEY (`code_id_code` ) REFERENCES `dbgestforma`.`code` (`id_code` ) ON DELETE NO ACTION ON UPDATE NO ACTION) ENGINE = InnoDB DEFAULT CHARACTER SET = latin1; -- ----------------------------------------------------- -- Table `dbgestforma`.`evenement` -- ----------------------------------------------------- DROP TABLE IF EXISTS `dbgestforma`.`evenement` ; CREATE TABLE IF NOT EXISTS `dbgestforma`.`evenement` ( `id_event` INT NOT NULL AUTO_INCREMENT , `libelle` VARCHAR(45) NULL , PRIMARY KEY (`id_event`) ) ENGINE = InnoDB; -- ----------------------------------------------------- -- Table `dbgestforma`.`historique` -- ----------------------------------------------------- DROP TABLE IF EXISTS `dbgestforma`.`historique` ; CREATE TABLE IF NOT EXISTS `dbgestforma`.`historique` ( `id_historique` INT NOT NULL AUTO_INCREMENT , `datetime_event` DATETIME NULL , `description` VARCHAR(100) NOT NULL , `tuteur_id_tuteur` INT(3) NOT NULL , `agent_id_agent` INT(3) NOT NULL , `salle_id_salle` INT(3) NOT NULL , `horaire_id_horaire` INT(3) NOT NULL , `code_id_code` INT(5) NOT NULL , `session_horaire_id_horaire` INT(3) NOT NULL , `session_agent_id_agent` INT(3) NOT NULL , `session_tuteur_id_tuteur` INT(3) NOT NULL , `session_salle_id_salle` INT(3) NOT NULL , `session_code_id_code` INT(5) NOT NULL , `event_id_event` INT NOT NULL , PRIMARY KEY (`id_historique`, `tuteur_id_tuteur`, `agent_id_agent`, `salle_id_salle`, `horaire_id_horaire`, `code_id_code`, `session_horaire_id_horaire`, `session_agent_id_agent`, `session_tuteur_id_tuteur`, `session_salle_id_salle`, `session_code_id_code`, `event_id_event`) , INDEX `fk_historique_tuteur` (`tuteur_id_tuteur` ASC) , INDEX `fk_historique_agent` (`agent_id_agent` ASC) , INDEX `fk_historique_salle` (`salle_id_salle` ASC) , INDEX `fk_historique_horaire` (`horaire_id_horaire` ASC) , INDEX `fk_historique_code` (`code_id_code` ASC) , INDEX `fk_historique_session` (`session_horaire_id_horaire` ASC, `session_agent_id_agent` ASC, `session_tuteur_id_tuteur` ASC, `session_salle_id_salle` ASC, `session_code_id_code` ASC) , INDEX `fk_historique_event` (`event_id_event` ASC) , CONSTRAINT `fk_historique_tuteur` FOREIGN KEY (`tuteur_id_tuteur` ) REFERENCES `dbgestforma`.`tuteur` (`id_tuteur` ) ON DELETE NO ACTION ON UPDATE NO ACTION, CONSTRAINT `fk_historique_agent` FOREIGN KEY (`agent_id_agent` ) REFERENCES `dbgestforma`.`agent` (`id_agent` ) ON DELETE NO ACTION ON UPDATE NO ACTION, CONSTRAINT `fk_historique_salle` FOREIGN KEY (`salle_id_salle` ) REFERENCES `dbgestforma`.`salle` (`id_salle` ) ON DELETE NO ACTION ON UPDATE NO ACTION, CONSTRAINT `fk_historique_horaire` FOREIGN KEY (`horaire_id_horaire` ) REFERENCES `dbgestforma`.`horaire` (`id_horaire` ) ON DELETE NO ACTION ON UPDATE NO ACTION, CONSTRAINT `fk_historique_code` FOREIGN KEY (`code_id_code` ) REFERENCES `dbgestforma`.`code` (`id_code` ) ON DELETE NO ACTION ON UPDATE NO ACTION, CONSTRAINT `fk_historique_session` FOREIGN KEY (`session_horaire_id_horaire` , `session_agent_id_agent` , `session_tuteur_id_tuteur` , `session_salle_id_salle` , `session_code_id_code` ) REFERENCES `dbgestforma`.`session` (`horaire_id_horaire` , `agent_id_agent` , `tuteur_id_tuteur` , `salle_id_salle` , `code_id_code` ) ON DELETE NO ACTION ON UPDATE NO ACTION, CONSTRAINT `fk_historique_event` FOREIGN KEY (`event_id_event` ) REFERENCES `dbgestforma`.`evenement` (`id_event` ) ON DELETE NO ACTION ON UPDATE NO ACTION) ENGINE = InnoDB;

par furiouslol » 08 déc. 2008, 22:31

Une clé étrangere, c'est un champs presque comme les autres et biensur qu'on peut le faire sous myAdmin, heureusement d'ailleurs

Tiens si t'es pas a l'aise avec le concept tu peux lire ce tutoriel : http://www.phpfrance.com/forums/voir_sujet-21507.php

Mais oui dans presque toutes les tables il y a des clé étrangere, qui permettent justement de faire le lien entre les tables, elles font partie du conceptuel de ta base de donnée

Par exemple, ta table agent regroupe toutes les informations relatives a un agent, ou en tout cas les informations dont tu as besoin, et qui lui apartiennent a lui seul, et en un exemplaire
Ensuite tu as les historiques (historique de quoi d'ailleurs ^^), et donc dans la table historique, et comme pour al table agent, tu vas regrouper dedans toutes les informations uniques d'un historique, a savoir la date et la description bien sur, mais aussi quel agent a provoqué la création de cet historique, et donc son id_agent, qui est unique, puisque clé primaire de ta table agent.

Si tu suis mon raisonnement on peut dire que la table historique joue le role de "liste" pour al table agent ... Si le nom et le prenom sont des données inhérente a chaque agent, on peut dire que la liste des historique d'un agent est aussi une donnée inhérente de cet agent, et en SQL c'est comme cela qu'on représente une liste, une ensemble de donnée stockées dans une autre table et repérée par un id, la fameuse foreign key

par Cypher_PHP » 08 déc. 2008, 18:56

je m'en doutais qu'il fallait créer une clé étrangère

mais sous phpmyadmin, on ne peut pas créer une clé étrangère, hein?

par Rei Itchido » 08 déc. 2008, 18:42

Pour chaque agent tu veux récupérer l'historique qui le concerne c'est ça?
Si c'est le cas il faut que tu stockes dans la table historique une référence à l'agent concerné pour pouvoir faire le lien. Et l'id de l'agent est là pour ça. On appelle ça une clé étrangère.
Derrière tu feras tes requêtes en joignant les 2 tables sur cet id qui fais le lien.
Tu saisis?

par Cypher_PHP » 08 déc. 2008, 18:38

bah, je crois que vous me comprenez pas ou que je m'exprime mal (je suis mauvais en français, excuse moi)
mais j'essaie d'expliquer clairement
bref, je vous montre mes données de la table agent
id_agent nom prenom id_session session
Modifier Effacer 35 ARDENOY GILLES 4 Init Word 2007
Modifier Effacer 37 VAUTHIER Slimane 2 Init Word 2007
Modifier Effacer 38 VAUTHIER Sylvie 4 Init Word 2007
Modifier Effacer 39 BOUCHONNEAU GILLES
et ceux de la table historique
id_historique datetime_event description
Modifier Effacer 4 2008-11-21 15:05:17 Ajout d'un tuteur: BOUCHONNEAU GILLES
Modifier Effacer 5 2008-11-21 15:10:16 Ajout d'un agent: FIQUET FABIEN
Modifier Effacer 6 2008-11-21 15:12:07 Ajout d'un tuteur: LAVILLAUROY Sylvain
Modifier Effacer 7 2008-11-21 15:13:31 Modification du tuteur: BOUCHONNEAU Gaston

par Rei Itchido » 08 déc. 2008, 18:28

Mais sans lien entre agent et historique, comment vas-tu savoir quel historique correspond à quel agent?

par Cypher_PHP » 08 déc. 2008, 18:26

bien je vais vous expliquer

j'ai une liste qui affiche tous les résultats qui contiennent tous les noms dans l'espace admin
mais sur l'espace membres, on n'affiche pas tout, bien sur.
donc je propose qu'on affiche une partie de liste en fonction de son nom.

suis -je me fait bien comprendre?

merci beaucoup

par zeus » 08 déc. 2008, 18:20

Il faut absolument un lien entre les tables si tu veux récupérer des données liées.

Alors, soit tu veux interdir l'exécution de la requête si une condition n'est pas respectée, dans ce cas, il faut 2 requêtes et un traitement serveur.
Soit tu veux récupérer les données de table_1 pour lesquelles tel champ vaut tel données de la table_2.

par Rei Itchido » 08 déc. 2008, 18:18

Ca n'a aucun sens non plus.

Que veux-tu faire exactement? Exprime-le avec des mots je veux dire.

par Cypher_PHP » 08 déc. 2008, 18:17

j'ai essayé cette requête et il affiche aucun enregistrement
raté...

Code : Tout sélectionner

SELECT * FROM historique WHERE id_historique IN(SELECT * FROM agent WHERE nom ="Bouche")

par Rei Itchido » 08 déc. 2008, 18:15

Que veux-tu faire exactement?
Ça n'a ni queue ni tête ce que tu essayes là.

par Cypher_PHP » 08 déc. 2008, 17:56

ah j'ai cru qu'une jointure pourrait faire l'affaire....

sinon je pense à ce genre de syntaxe:
je sais pas si c'est faisable...
d'ailleurs, ej vais tester de suite

Code : Tout sélectionner

SELECT * FROM historique WHERE SELECT nom FROM agent WHERE nom ="'.$_SESSION['sn'].'"