Vous n'êtes pas identifié(e).
Bonjour,
Je suis vraiment désolé, mais entre les fêtes et le boulot, j'ai la tête sous l'eau... Je reviens vers toi d'ici la fin de la semaine.
Bonnes fêtes de fin d'année.
++
POO PHP+Ajax en MVC avec PDO et Bases de données épaisses : What else?
Hors ligne
Ok, pas de soucis, c t surtout pour etre sur que tu n'attendais pas qqchose de moi ^^
Respire et reviens
Hors ligne
Bonjour,
Alors désolé pour tout ce temps mis, mais boulot boulot, et encore tu vois à qu'elle heure j'ecris ce post un dimanche...
Cela a été galère car j'ai du me relire quasiment tout le contenu du post pour me remettre dans le bain de la structure de tes tables.
En fait pour ta procédure stockée, il te manquait l'info id_pseudo associée à chaque pet du tiercé gagnant, car c'est la clé primaire de la table à mettre à jour pour les gains, et la table m_course2 ne contient que l'id_course et l'id_pet.
Donc voici quel devrait être ta procédure (j'ai pas test)
CREATE PROCEDURE set_course_gains(id_course INT)
BEGIN
DECLARE pos INT DEFAULT 0;
DECLARE basevalue INT DEFAULT 60;
DECLARE nbpart INT;
DECLARE idpet INT;
DECLARE idpseudo INT;
DECLARE qte_ress INT;
DECLARE type_ress INT;
DECLARE gains INT;
DECLARE cur1 CURSOR FOR SELECT id_pet,id_pseudo, nb_participants, ressource_quantite, ressource_type
FROM m_course2 LEFT JOIN pet ON m_course2.id_pet=pet.id_pet
WHERE id_course=id_course ORDER BY dist_parcourue DESC LIMIT 3;
OPEN cur1;
START TRANSACTION;
REPEAT
FETCH cur1 INTO idpet,idpseudo,nbpart,qte_ress,type_ress;
SET pos=pos+1;
IF pos=2 THEN basevalue=20;
IF pos=3 THEN basevalue=10;
SET gains=(basevalue/qte_ress*nbpart))*100;
UPDATE perso_ressource SET p_ressource_type=type_ress+gain WHERE id_pseudo=idpseudo;
UNTIL pos=3 END REPEAT;
COMMIT;
CLOSE cur1;
END
Note: J'ai rajouté le mode transactionnel dans la procédure mais tu peux le retirer car il n'est ici pas complet pour être efficace et jouer son rôle pleinement. En effet il faudrait créer un handler et vérifier à chaque itération les status d'erreurs mySQL retourné par chaque mise à jour pour pouvoir faire un rollback et sortir de la procédure au moindre problème rencontré. Dans ce cas, il te faut rajouter un OUT errMSG CHAR en paramètre de la procédure, et lui passer l'erreur complète rencontrée de manière à pouvoir la remonter à l'utilisateur.
Bonne lecture et bon dimanche à toi
++
Dernière modification par Jc (29-01-2012 07:12:53)
POO PHP+Ajax en MVC avec PDO et Bases de données épaisses : What else?
Hors ligne
Oui je vois que tu as été matinal
Alors il y a 1 erreurs ligne 23 et 1 ligne 24, il faut mettre plutot
Mais il me met toujours une erreur que j'arrive pas a résoudre :
MySQL a répondu:
#1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '=20;
IF pos=3 THEN basevalue=10;
SET gains=(basevalue/qte_ress*nbp' at line 21
Sinon, je remarque que la on déclarer une Procedure alors que pour mon autre cas (calcule de position - page3) on avait déclarer une fonction. Je suppose donc que ce n'est pas la meme chose?
Merci
Hors ligne
Oui, désolé je pense que j'ai du oublié "END IF;" à la fin de chaque ligne IF pos..
Oui la procédure n'a rien à voir avec la fonction. Elle s'appele via un CALL (à la place d'un select).
++
POO PHP+Ajax en MVC avec PDO et Bases de données épaisses : What else?
Hors ligne
Ah voila, il manquait aussi le SET (dans les if then)
J'ai enfin pu créer la procéduire suivante :
Reste a voir si elle fait ce qu'on voulait
je continu donc ...
Dernière modification par ebouilleur (29-01-2012 15:37:57)
Hors ligne
Ca ne fonctionnera pas, tu as changé le paramètre en OUT alors qu'il doit être en IN (valeur par défaut)
Dernière modification par Jc (29-01-2012 16:05:30)
POO PHP+Ajax en MVC avec PDO et Bases de données épaisses : What else?
Hors ligne
Re, il y a un truc qui me chagrine,
La définition de ta table perso_ressource c'etait bien
CREATE TABLE IF NOT EXISTS `perso_ressource` (
`id_pseudo` int(11) NOT NULL auto_increment,
`bois` int(10) unsigned NOT NULL,
`herbe` int(10) unsigned NOT NULL,
`viande` int(10) unsigned NOT NULL,
`plante` int(10) unsigned NOT NULL,
`fer` int(10) unsigned NOT NULL,
`angreal` int(10) unsigned NOT NULL,
`quartz` int(10) unsigned NOT NULL,
UNIQUE KEY `id_pseudo` (`id_pseudo`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=28567 ;
Or à la ligne 23 de ta procédure, il s'agit d'augmenter pour le propriétaire du pet, sa reserve de ressource concernée par la course par son gain. Tu as visiblement un problème de modélisation. En effet tu défini dans la table course, un type de ressource en tinyint et une quantité et tu n'as aucune correspondance dans ta modélisation avec la table perso_ressource dans laquelle tu listes toutes les ressources par libellé. Ce n'est donc pas correct. Il te faut refaire ta modélisation.
Il te faudrait une table pour définir tes ressources du style
table ressources : id tinyint unsigned not null auto_increment en clé primaire avec un lib varchar pour les libellés ressources.
Ensuite si ton type de ressource corresponds directement à ta ressource tu places une clé étrangère sur type_ressource dans ta table course faisant référence à ton id de ta table ressources, et tu crées une table de jonction pour définir l'ensemble des richesses par id_pseudo, du style
table richesses_joueur
id_pseudo int unsigned not null
id_ressource tinyint unsigned not null
qte int unsigned not null
avec une clé primaire composite définie sur id_pseudo et id_ressource.
Ainsi pour mettre à jour tes gains, il te suffit à la ligne 23 de faire,
Sinon cela ne pourra pas fonctionner.
PS: dans ton modèle actuel, si tu as demain 50 ressources à gérer tu vas te retrouver avec une table perso_ressources de 50 colonnes. C'est un modèle complètement dénormalisé, et ce n'est pas viable du tout.
++
Dernière modification par Jc (29-01-2012 16:39:23)
POO PHP+Ajax en MVC avec PDO et Bases de données épaisses : What else?
Hors ligne
OK, autant pour moi...
J'arrive pas a trouver d'exemple concret d'intégration de procédure dans du code php.
J'ai essayé :
Mais la requete ne fonctionne pas sous pma
J'étais en train de réfléchgir a tout ca, mais la avec ton post je me sens obligé de te répondre de suite.
Je ne saisi pas trop le probleme.
Dans ma page d'inscription a la course (que tu ne connais pas), quand le pet valide sa participation, la ressource demandée pour participé est retiré de son stock.
Sinon, je sais que bois=1 ; herbe=2 ; viande=3 etc... et ce numéro de correspondance est stocké dans la variable ressource_type de la table course
OK je viens de comprendre ce que tu veux dire.
J'avais zapé ce "détail", mais c'est pour ca que je t'avais glissé ma fonction php dans la page précédente :
// trouve le nom d'une ressource en fct de son numéro
{
switch ($ressource)
{
case '1':
$nom = "Bois";
break;
case '2':
$nom = "Herbe";
break;
case '3':
$nom = "Viande";
break;
case '4':
$nom = "Plante";
break;
case '5':
$nom = "Fer";
break;
case '6':
$nom = "Angreal";
break;
}
return $nom;
}
C'était pour éventuellement l'intégré dans la procédure...
mais sinon oui faire une table de correspondance ca peut etre utile
PS: dans ton modèle actuel, si tu as demain 50 ressources à gérer tu vas te retrouver avec une table perso_ressources de 50 colonnes. C'est un modèle complètement dénormalisé, et ce n'est pas viable du tout.
Je n'aurais pas d'autres ressources, mais ok admettons, il faudrai mieux faire quoi? 1 table avec 3 colonnes (type_ressource, quantite, id_pseudo) ?
Oui je suis bete, tu l'as indiqué...
Dernière modification par ebouilleur (29-01-2012 16:44:07)
Hors ligne
Pour l'utilisation de ta procédure, c'est pas plus compliqué que cela:
Dernière modification par Jc (29-01-2012 16:44:51)
POO PHP+Ajax en MVC avec PDO et Bases de données épaisses : What else?
Hors ligne
Heu, t'es sur? (enfin je suppose) mais id_course ne devrait pas etre une variable plutot?
parce que, si je colle CALL set_course_gains(id_course) sous pma, ca me donne :
requête SQL:
CALL set_course_gains(
id_course
)
MySQL a répondu:
#1054 - Unknown column 'id_course' in 'field list'
Hors ligne
Il ne s'agit pas de faire une table de correspondance, il s'agit de créer une table de définition de ressouces, et de créer une table de jonction joueur_ressources pour définir qu'elles sont les richesses d'un joueur en terme de ressources. De façon générale, on ne doit pas encoder en dur les paramètres en PHP.... tu dois pouvoir créer modifier tes types de ressources sans toucher à ton code.
POO PHP+Ajax en MVC avec PDO et Bases de données épaisses : What else?
Hors ligne
tu as oublié le $ devant id_course^^ (ayant fait un copier coller de ton code, j'ai mis à jour juste après..)
Dernière modification par Jc (29-01-2012 16:51:30)
POO PHP+Ajax en MVC avec PDO et Bases de données épaisses : What else?
Hors ligne
Ok, mais $id_course tout seul n'existe pas, non?
je peux pas le mettre comme ca dans le code (ligne 32) :
// on met a jour les ressources des 3 1er pet
$sqlUp = "CALL set_course_gains($id_course) ";
$result = mysql_query($sqlUp) ;
if ($result===false){throw new Exception("Erreur update ressource pet gagnant ",E_USER_NOTICE);}
// on met a jour la distance dans la table course_participant
$sqlUp = "UPDATE course_participant, m_course2
SET course_participant.distance=m_course2.dist_parcourue
WHERE course_participant.id_course=m_course2.id_course AND course_participant.id_pet=m_course2.id_pet ";
$result = mysql_query($sqlUp) ;
if ($result===false){throw new Exception("Erreur update course_participant",E_USER_NOTICE);}
// On archive les courses terminées.
$sqlUp = "UPDATE course
SET statut='5'
WHERE statut='3' ";
$result=mysql_query($sqlUp);
if ($result===false){throw new Exception("Erreur de maj des course au statut 5",E_USER_NOTICE);}
// on efface la table m_course2
$sqlDel = "DROP TABLE m_course2 ";
$result = mysql_query($sqlDel);
if ($result===false){throw new Exception("Erreur de suppression de la table memory course2",E_USER_NOTICE);}
// On commence par clôturer les courses en cours qui sont terminées.
$sqlUp = "UPDATE course,pet
SET course.statut=3, pet.oqp=0
WHERE (UNIX_TIMESTAMP(NOW())-UNIX_TIMESTAMP(depart_theorique)) > (duree*60) AND statut=2 ";
$result=mysql_query($sqlUp);
if ($result===false){throw new Exception("Erreur de Maj cloture course",E_USER_NOTICE);}
echo "<b>Archives des couses et cloture ok</b>";
}#go_statut3
Dernière modification par ebouilleur (29-01-2012 16:53:48)
Hors ligne
Il te faut extraire l'info $id_course de ton code en amont. Tu dois bien l'avoir quelque part. En cas si tu es obligé de faire un select pour le récupérer, pour économiser une requête remonte l'info dans m_course2, et comme cela tu n'en a plus besoin: tu retires le paramètres à ta procédure et tu le récupère directement dans ta procédure via m_course2.
Juste pour info, normalement le calcul des gains doit se faire après la mise à jour des distances parcourues..
Dernière modification par Jc (29-01-2012 17:01:17)
POO PHP+Ajax en MVC avec PDO et Bases de données épaisses : What else?
Hors ligne
Sinon, pour ne pas cassé tout mon code actuel, je ne vais pas refaire ma table de ressources (mais je prend note de ta remarque pour le futur)
J'ai donc créé la table :
--
-- Contenu de la table `ressources`
--
INSERT INTO `ressources` (`id_ressource`, `nom`) VALUES
(1, 'bois'),
(2, 'herbe'),
(3, 'viande'),
(4, 'plante'),
(5, 'fer'),
(6, 'angreal');
Et j'ai modifié la procédure en :
Qu'en penses tu?
Dernière modification par ebouilleur (29-01-2012 17:11:38)
Hors ligne
Non c'est pas bon, pas la table mais ta requête de mise à jour. On n'additionne pas un nom avec une quantité... enfin en Alsace on ne le fait pas et tu as enlevé les SET dans les deux lignes qui précèdent la mise à jour.
Dernière modification par Jc (29-01-2012 17:05:47)
POO PHP+Ajax en MVC avec PDO et Bases de données épaisses : What else?
Hors ligne
OK, j'ai oublié des parenthèses, mais sinon, on peut le faire
en tout cas ca fonctionne quand je le fais comme ca :
Bon après l'Alsace, je ne connais pas donc bon
Dernière modification par ebouilleur (29-01-2012 17:09:12)
Hors ligne
Sinon, pour ne pas cassé tout mon code actuel, je ne vais pas refaire ma table de ressources (mais je prend note de ta remarque pour le futur)
C'est bien pour cela que normalement, on modélise avant de coder
POO PHP+Ajax en MVC avec PDO et Bases de données épaisses : What else?
Hors ligne
ebouilleur a écrit :Sinon, pour ne pas cassé tout mon code actuel, je ne vais pas refaire ma table de ressources (mais je prend note de ta remarque pour le futur)
C'est bien pour cela que normalement, on modélise avant de coder
Ouais, c'est sur... mais plus jamais je n'embarquerai dans un si gros projet tout seul.. qui traine dans le temps.. et qui en profite pour évoluer
Sinon, pour continuer sur les modif sur la procédure, ca donne :
Mais, ce qui me chagrine (chacun son tour), c'est id_course.
OK je le prend dans m_course2... mais je le compare a quoi?
Dernière modification par ebouilleur (29-01-2012 17:14:06)
Hors ligne
Et juste pour info, tous tes paramètres tu les récupères comment? Je te rappele qu'une seule ressource est concernée dans ton modèle actuel par la mise à jour, et ton défaut de normalisation fait que tu es actuellement incapable de renseigner la bonne ressource pour la mise à jour, sauf si tu intégres ta fonction de correspondance de ressource dans ta procédure.
Dernière modification par Jc (29-01-2012 17:12:25)
POO PHP+Ajax en MVC avec PDO et Bases de données épaisses : What else?
Hors ligne
Mon exemple de requete étais juste une illustration, par pour ce cas précis.
Dans notre cas, on a type_ressource.
On a le nom correspondant via la table ressource (ligne 14 : LEFT JOIN ressources ON ressources.id_ressource=m_course2.ressource_type)
Donc ca va non?
Hors ligne
Si mes souvenirs sont bon, dans m_course2, tu n'as qu'une seule course, celle que tu dois cloturer. Donc en fait, finalement tu n'en à pas besoin
Enfin si, il te faut quand même le récupérer dans ton fetch. Ensuite, si tu ne veux pas recoder l'existant, comme je te disais, il te faut intégrer ta fonction de correspondance dans ta fonction... que de lignes inutiles mais bon.. et je ne suis pas certain que ta combine pour le type de ressource soit accepté dans ta procédure, même si normalement ca devrait (désolé, je viens de comprendre aussi^^).
Donc cela devrait donner ceci
Dernière modification par Jc (29-01-2012 17:30:59)
POO PHP+Ajax en MVC avec PDO et Bases de données épaisses : What else?
Hors ligne
Si mes souvenirs sont bon, dans m_course2, tu n'as qu'une seule course, celle que tu dois cloturer. Donc en fait, finalement tu n'en à pas besoin
Humm.... dans m_course2 j'ai toutes les courses qui sont fini.
Donc faudrait peut etre faire un GROUP BY id_course dans cette partie :
DECLARE cur1 CURSOR FOR SELECT id_pet,id_pseudo, nb_participants, ressource_quantite, ressource_type,nom
FROM m_course2 LEFT JOIN pet ON m_course2.id_pet=pet.id_pet
LEFT JOIN ressources ON ressources.id_ressource=m_course2.ressource_type
ORDER BY dist_parcourue DESC LIMIT 3;
Non?
Dernière modification par ebouilleur (29-01-2012 17:40:55)
Hors ligne
... ?? t'es sur?? le prefixe m_ signifie dans ma nomenclature table de type memory, et on les drop à la fin de chaque cron non? Il ne s'agit pas de la table course qui contient les courses en cours et les archivées normalement (c'est le statut qui les différencie dans la table course).
Dernière modification par Jc (29-01-2012 17:43:27)
POO PHP+Ajax en MVC avec PDO et Bases de données épaisses : What else?
Hors ligne