Page 1 sur 1

insertion automatique dans une table liée

Posté : 29 mai 2007, 11:28
par jed
Bonjour, voici mon problème: j'ai une table qui se constitue comme ceci:

Code : Tout sélectionner

CREATE TABLE formations ( id INT NOT NULL PRIMARY KEY AUTO_INCREMENT, nom VARCHAR(50) )ENGINE=INNODB; CREATE TABLE matieres ( id INT NOT NULL PRIMARY KEY AUTO_INCREMENT, nom VARCHAR(50), id_formation INT NOT NULL, INDEX (id_formation), FOREIGN KEY (id_formation) REFERENCES formations(id) ON UPDATE CASCADE ON DELETE CASCADE )ENGINE=INNODB; CREATE TABLE stagiaires ( id INT NOT NULL PRIMARY KEY AUTO_INCREMENT, nom VARCHAR(20), prenom VARCHAR(20), telephone VARCHAR(20), id_formation INT NOT NULL, FOREIGN KEY (id_formation) REFERENCES formations(id) ON UPDATE CASCADE ON DELETE CASCADE )ENGINE=INNODB ; CREATE TABLE competences ( id INT NOT NULL PRIMARY KEY AUTO_INCREMENT, nom VARCHAR(20), id_matiere INT NOT NULL, INDEX (id_matiere), FOREIGN KEY (id_matiere) REFERENCES matieres(id) ON UPDATE CASCADE ON DELETE CASCADE )ENGINE=INNODB; CREATE TABLE acquerir ( id_stagiaire INT NOT NULL, id_competence INT NOT NULL, PRIMARY KEY(id_stagiaire, id_competence), vrai INT default 0, FOREIGN KEY (id_stagiaire) REFERENCES stagiaires(id) ON UPDATE CASCADE ON DELETE CASCADE, FOREIGN KEY (id_competence) REFERENCES competences(id) ON UPDATE CASCADE ON DELETE CASCADE )ENGINE=INNODB ;
J'aimerais que lorsque j'ajoute un stagiaire, un nouvel enregistrement s'effectue dans la table 'acquerir' sans y effectuer de requête, est ce possible? Merci.

Posté : 29 mai 2007, 11:39
par Hubert Roksor
Pas d'après ce que je vois. Je viens d'essayer sous MySQL 5.0.37 à l'aide de ton schéma et je n'ai pas eu d'enregistrement apparaissant spontanément. Quelles sont les valeurs de l'enregistrements en question ? J'imagine que id_stagiaire correspond à celui que tu viens d'insérer, mais quid des autres ?

Posté : 29 mai 2007, 11:43
par jed
Voila le shéma: un stagiaire dépend d'une formation. Une matière dépend d'une formation. Une compétence dépend d'une matière. Un résultat (acquérir) dépend d'un stagiaire et d'une compétence. Je souhaite donc qu'un enregistrement s'effectue dans 'acquérir' avec 'vrai' a defaut (0) à chaque enregistrement dans 'stagiaires'. J'ai essayé de modifier ma table 'acquérir' de la manire suivante:

Code : Tout sélectionner

CREATE TABLE acquerir ( id_stagiaire INT NOT NULL, id_competence INT NOT NULL, PRIMARY KEY(id_stagiaire, id_competence), vrai INT, FOREIGN KEY (id_stagiaire) REFERENCES stagiaires(id) ON UPDATE SET NULL ON DELETE CASCADE, FOREIGN KEY (id_competence) REFERENCES competences(id) ON UPDATE CASCADE ON DELETE CASCADE )ENGINE=INNODB ;
Mais phpmyadmin me renvoit cette erreur: "#1005 - Can't create table '.\greta\acquerir.frm' (errno: 150)"

Posté : 29 mai 2007, 11:50
par leakcim51
Bonjour,
si tu veux qu'un enregistrement soit ajouté sans te taper la requête, tu peux essayer les triggers.
ON INSERT, ON UPDATE, ON DELETE
Bon courage

Posté : 29 mai 2007, 12:36
par Hubert Roksor
Mince, j'avais lu le topic à l'envers, je croyais qu'un enregistrement apparaissait spontanément sans que tu saches pourquoi alors que c'est le contraire. Je repasserai plus tard si t'as pas résolu ton topic.

Posté : 29 mai 2007, 13:41
par jed
Me revoilà, je me suis documenté sur les triggers et j'ai essayé d'en ajouter un mais je pense que ca résoudera pas le problème...

Posté : 29 mai 2007, 14:37
par jed
J'ai essayé avec le code suivant pour des tables en myisam mais oblige à des requêtes supplémentaires et il reste un problème avec l'id du stagiaire qui reste à 0...
if (isset($_POST['id_eleve']) && isset($_POST['nom_eleve']) && isset($_POST['prenom_eleve']) && isset($_POST['id_formation']) && isset($_POST['tel']))
{
	if ($_POST['id_eleve'] == 0)
	{
		$insert = mysql_query ('INSERT INTO stagiaires VALUES ("", "'.$_POST['nom_eleve'].'", "'.$_POST['prenom_eleve'].'", "'.$_POST['tel'].'", "'.$_POST['id_formation'].'")');
		$query = mysql_query ('SELECT id FROM competences');
		while ($sql = mysql_fetch_object($query))
		{
			$db = mysql_query ('INSERT INTO acquerir VALUES ("","'.$_POST['id_eleve'].'", "'.$sql->id.'", "0")') or die (mysql_error());
		}
	}

Posté : 30 mai 2007, 07:13
par Hubert Roksor
je me suis documenté sur les triggers et j'ai essayé d'en ajouter un mais je pense que ca résoudera pas le problème...
Et pourtant c'est exactement ce qu'il faut que tu utilises. Quelle version de MySQL utilises-tu ?

Dans ton précédent message tu disais que tu voulais un enregistrement pour chaque stagiaire avec la colonne "vrai" à 0, mais que mets-tu comme valeur dans la colonne "id_competence" ? D'où tiens-tu cette valeur lors de l'insertion ?

Concernant le bout de code que tu as posté, ce passage
if (isset($_POST['id_eleve']) && isset($_POST['nom_eleve']) && isset($_POST['prenom_eleve']) && isset($_POST['id_formation']) && isset($_POST['tel']))
peut être remplacé par
if (isset($_POST['id_eleve'], $_POST['nom_eleve'], $_POST['prenom_eleve'], $_POST['id_formation'], $_POST['tel']))
De plus il faut impérativement que tu passent toutes tes valeurs par mysql_real_escape_string().

Posté : 30 mai 2007, 09:16
par jed
Merci pour cette info ;) Je dois, dans le colonne "id_competence", insérer chaque id de la table "compétences", de manière a effectuer une sorte de boucle qui insère un enregistrement pour le stagiaire qui vient d'être ajouter tant qu'il existe des compétences. En php, ça donnerait:
$stagiaire = mysql_query ('INSERT INTO stagiaires VALUES ("$id_stagiaire", "$nom", "$prenom")');

$response = mysql_query ('SELECT id FROM competences ORDER BY id');
while ($sql = mysql_fetch_object ($response))
{
       $insert = mysql_query ('INSERT INTO aquerir VALUES ("$id_stagiaire" // l'id du stagiaire que l'on a précédement inséré
       , "$sql->id // l'id de chaque compétence
       , "0")'); // champs "vrai" à 0
}

Posté : 30 mai 2007, 15:45
par Hubert Roksor
Hmm, quel est l'intérêt d'insérer plein d'enregistrements à 0 ? le mieux serait je pense de n'insérer que ceux qui doivent être à 1, et si jamais tu as besoin d'un rapport pour toutes les compétences tu peux utiliser une jointure externe. Par exemple:

Code : Tout sélectionner

SELECT c.id, c.nom, COALESCE(a.vrai, 0) AS vrai FROM competences c LEFT JOIN acquerir a ON a.id_competence = c.id AND a.id_stagiaire = 123
Ça a entre autres avantages celui de ne pas nécessiter de maintenance lorsque tu ajoutes une compétence (sinon il faut réinsérer un enregistrement à 0 pour chaque stagiaire :arrow: pas glop). Qu'en penses-tu ?

Posté : 30 mai 2007, 15:50
par jed
C'est parce que je dois afficher les résultats des élèves qui sont à leur entrée "non acquis". Mais une image vaut mieux qu'un long discours:

Image

Il faut donc qu'a chaque enregistrement d'un élève, les résultats s'affichent à "non acquis" pour chaque compétence.

Posté : 30 mai 2007, 15:52
par Hubert Roksor
Oui, je m'en doutais un peu en fait, mais ça ne contredit pas ce que je disais plus haut, à savoir que tu n'as pas besoin d'insérer des enregistrements vides, SQL est fait pour ça. Essaie la requête du dessus, ça devrait te donner la liste des compétences acquises ou non, sans nécessiter d'enregistrements à zéro. (et au passage tu pourrais virer ta colonne "vrai" puisque la seule valeur serait 1)

Posté : 30 mai 2007, 15:57
par jed
Ok, je vais essayer ça merci ;) . Est-ce compatible avec des contraintes ON UPDATE et ON DELETE?

Posté : 30 mai 2007, 16:13
par Hubert Roksor
Ben dans la mesure où tu ne fais qu'insérer moins de données ça ne change rien donc oui.