JeuWeb - Crée ton jeu par navigateur
[Resolu] SQL: de l'UPDATE à l'INSERT - Version imprimable

+- JeuWeb - Crée ton jeu par navigateur (https://jeuweb.org)
+-- Forum : Discussions, Aide, Ressources... (https://jeuweb.org/forumdisplay.php?fid=38)
+--- Forum : Programmation, infrastructure (https://jeuweb.org/forumdisplay.php?fid=51)
+--- Sujet : [Resolu] SQL: de l'UPDATE à l'INSERT (/showthread.php?tid=6639)

Pages : 1 2


[Resolu] SQL: de l'UPDATE à l'INSERT - zneman - 11-02-2013

Salut tout le monde ! Me revoilà, après deux ans d'absence dans le monde de la prog et du jeu (pas mal occupé on va dire).

Donc déjà: Je suis content de voir que ce super forum existe toujours et que certaines têtes connues soient toujours bien actives ici !

Là n'est pas le problème, je reviens avec du lourd lourd ! (pour moi du moins).

J'explique:

j'ai une table t_troupe qui contient (grosso modo) toutes les troupes du joueurs, sous la forum:

PK_troupe (juste la clé primaire qui s'auto-incrémente)
FK_joueur (qui se réfère à la clé primaire du joueur qui possède la troupe)
FK_cTroupe (qui va donc chercher les statistiques de la troupe, nom, prix, force etc...)
nombre (le nombre que ce joueur en possède)
type (0,1) (détermine si la troupe est en attaque ou défense !

Bref, le problème étant que dans mes scripts je veux MODIFIER les troupes du joueurs !
SAUF que dans certains cas (si par exemple le joueur n'a jamais eu de troupe de ce genre), je ne peux pas modifier vu qu'il n'existe PAS de ligne de cette troupe pour ce joueur.

Vous arrivez à me suivre ? Tongue

J'ai alors découvert qu'il existe un type de requête qui créé cette ligne si elle ne peut la modifier !
=> ON DUPLICATE KEY UPDATE
Manque de chance, sur cela, on ne peut utiliser la fonction WHERE et on doit utilisé une clé primaire...

J'ai donc testé ce genre de truc:

Code :
INSERT INTO t_troupe (FK_joueur, FK_cTroupe, nombre, type)
VALUES (9, 2, 200, '0')
ON DUPLICATE KEY UPDATE
FK_joueur = 9 AND FK_cTroupe = 2;

Mais ça ne fait qu'ajouter une ligne sans rien modifier ! Bref, j'ai du mal...

Alors il y a cette solution (qui ne marche pas vraiment pour l'instant) ou alors:

- vérifier avant chaque update que cette ligne de troupe existe (ce qui risque de faire mal en requête surtout si on a beaucoup de troupes à modifier
- ajouter directement toutes les lignes des troupes lors de l'inscription du joueur, et faire une verif/insertion lors de la connexion du joueur (dans le cas où j'ajoute une troupe à la BDD par exemple)

Bref, vous voyez, j'ai du mal à bien revenir dans le bain, et vos avis me seraient donc assez utiles Smile

Merci d'avance !

PS: au passage: Bonne année, avec un peu de retard Big Grin


RE: SQL: de l'UPDATE à l'INSERT - Holy - 11-02-2013

Logiquement, l'update sur la duplication fonctionne très bien si tu as bien une double clé primaire sur fk_joueur et pk_troupe.


RE: SQL: de l'UPDATE à l'INSERT - zneman - 11-02-2013

Elles ne sont justement pas des clés primaires ! (je voulais tester ainsi en fait).
On peut mettre 3 clés primaires dans une table ? ^^ (j'ai entendu parler de clés composites mais je suis pas sûr d'avoir bien tout compris)


RE: SQL: de l'UPDATE à l'INSERT - Holy - 11-02-2013

(11-02-2013, 09:54 PM)zneman a écrit : Elles ne sont justement pas des clés primaires ! (je voulais tester ainsi en fait).
On peut mettre 3 clés primaires dans une table ? ^^ (j'ai entendu parler de clés composites mais je suis pas sûr d'avoir bien tout compris)
A ma connaissance tu peux mettre autant de clés primaires que tu veux, mais je suis loin d'être un spécialiste en la matière Smile

Il te suffit de supprimer toutes tes clés primaires (si tu en as) puis tu rajoutes les trois en même temps Smile


RE: SQL: de l'UPDATE à l'INSERT - zneman - 11-02-2013

Je viens de faire quelques tests, ça ne semble pas vraiment vouloir :/
Ceci dit, je parle du ON DUPLICATE KEY UPDATE mais qu'en penses tu des autres solutions ?
Le problème étant qu'il faut trouver une solution stable et utilisable partout, y compris pour plusieurs UP de troupes etc...
En fait, plus ça va, plus je me dis que je devrais effectivement créer directement les lignes de troupes lors de la création du compte etc... :/


RE: SQL: de l'UPDATE à l'INSERT - Holy - 11-02-2013

Le on duplicate key update est la bonne façon de faire les choses. Peux-tu exporter la structure de ta table pour qu'on soit sûr que tes manips sont bonnes ?

J'ai déjà eu à gérer ce genre de cas et ça fonctionnait sans soucis Smile


RE: SQL: de l'UPDATE à l'INSERT - zneman - 11-02-2013

Code :
--
-- Structure de la table `t_troupe`
--

CREATE TABLE IF NOT EXISTS `t_troupe` (
  `PK_troupe` int(11) NOT NULL AUTO_INCREMENT,
  `FK_joueur` int(8) NOT NULL,
  `FK_cTroupe` int(3) NOT NULL,
  `nombre` int(11) NOT NULL,
  `type` set('0','1') NOT NULL COMMENT '0=defense, 1=attaque',
  PRIMARY KEY (`PK_troupe`)
) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=13 ;

Peut on, grâce à la méthode du ON DUPLICATE, up plusieurs lignes ? tables ? Les pages qui parlent de cette fonction le font trop rapidement je trouve.


RE: SQL: de l'UPDATE à l'INSERT - Holy - 11-02-2013

(11-02-2013, 10:36 PM)zneman a écrit :
Code :
--
-- Structure de la table `t_troupe`
--

CREATE TABLE IF NOT EXISTS `t_troupe` (
  `PK_troupe` int(11) NOT NULL AUTO_INCREMENT,
  `FK_joueur` int(8) NOT NULL,
  `FK_cTroupe` int(3) NOT NULL,
  `nombre` int(11) NOT NULL,
  `type` set('0','1') NOT NULL COMMENT '0=defense, 1=attaque',
  PRIMARY KEY (`PK_troupe`)
) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=13 ;
Sur cet export, il n'y a qu'une seule clé primaire, donc normal que la duplication ne fonctionne pas.

Tu dois d'abord retirer ton auto increment, puis virer la clé primaire, puis rajouter une triple clé primaire.
Code :
ALTER TABLE  `t_troupe` ADD PRIMARY KEY (  `PK_troupe` ,  `FK_joueur` ,  `FK_cTroupe` )

(oublie pas de rajouter à nouveau ton auto_increment sur ton champ PK_troupe.


RE: SQL: de l'UPDATE à l'INSERT - zneman - 11-02-2013

Merci pour l'aide, j'apprends des choses ! Big Grin
Voila donc pour les 3 PK: done !

Je viens en revanche de re-tester ma requête:

INSERT INTO t_troupe (FK_joueur, FK_cTroupe, nombre, type)
VALUES (9, 2, 200, '0')
ON DUPLICATE KEY UPDATE
FK_joueur = 9 AND FK_cTroupe = 2;

Alors soit: il y'a une erreur dans ma requète, soit ça ne fonctionne pas ! Ici il ne m'actualise rien, mais m'ajoute une ligne (une fois encore).


RE: SQL: de l'UPDATE à l'INSERT - Holy - 11-02-2013

(11-02-2013, 11:04 PM)zneman a écrit : Merci pour l'aide, j'apprends des choses ! Big Grin
Voila donc pour les 3 PK: done !

Je viens en revanche de re-tester ma requête:

INSERT INTO t_troupe (FK_joueur, FK_cTroupe, nombre, type)
VALUES (9, 2, 200, '0')
ON DUPLICATE KEY UPDATE
FK_joueur = 9 AND FK_cTroupe = 2;

Alors soit: il y'a une erreur dans ma requète, soit ça ne fonctionne pas ! Ici il ne m'actualise rien, mais m'ajoute une ligne (une fois encore).
En fait, c'est logique vu qu'à cause de l'incrementation, le champ PK_troupe sera toujours différent. Donc il te suffit de retirer la clé primaire sur FK_cTroupe et FK_joueur et de mettre un double index unique sur ces deux champs, ça devrait suffire (je viens de faire un test).