2009-10-15 5 views
1

J'ai une table qui contient les éléments que les utilisateurs de mon jeu possèdent. Si un utilisateur achète un nouvel élément, il devrait être inséré, mais s'il l'a déjà, il devrait être augmenté à la place. Je comprends que je peux utiliser INSERT ... ON DUPLICATE KEY UPDATE, mais je ne comprends pas comment dans mon problème.Comment insérer une ligne, mais en double; le mettre à jour à la place?

Le item_id n'est pas unique, car de nombreux joueurs peuvent posséder la même arme (c'est-à-dire un mot long). Le user_id n'est pas unique non plus, car un joueur peut posséder de nombreux objets.

Alors, ma question est de savoir comment faire la requête UPDATE au lieu de INSERT si une ligne contenant à la fois le user_id et item_id existe déjà?

Répondre

2

Ce n'est pas ce que le "ON DUPLICATE KEY UPDATE" fera pour vous. Si c'était moi, je tenterais l'insertion. Si cela a échoué, vérifiez pourquoi (vous vérifiez déjà les erreurs, n'est-ce pas?). Si c'est à cause d'une clé en double, faites votre mise à jour. Si l'erreur est due à une autre raison, prenez-la en charge de manière appropriée.

+0

La copie est détectée en fonction de la contrainte de clé primaire ou de toute autre contrainte/index unique sur la table. En fait, on dirait que vous avez une colonne "quantité". Si vous insérez une ligne, vous voulez que la quantité soit 1. Si vous mettez à jour parce que le joueur en a déjà 1, alors vous voulez que la quantité soit incrémentée ... ON DUP KEY UPDATE ne fera que rendre la ligne existante voulait insérer. Vous devrez faire comme je le suggère, ou chercher la présence de la rangée en premier. Je préfère mon chemin. –

+0

BTW, mon raisonnement: Vérification d'abord prend toujours deux requêtes. Essayer, et vérifier le résultat, ne prend que deux requêtes si c'est un dup. –

+0

Désolé, j'ai supprimé mon commentaire après votre modification. D'accord, je me demandais simplement s'il était possible de le faire avec seulement une requête. – Phoexo

2

Vous voulez SUR LA MISE À JOUR DE LA CLÉ DUPLICATE. Il recherche la clé primaire de la table et, si elle existe, met à jour toutes les autres lignes.

donc votre table a une clé primaire de (userid, itemid) et les valeurs suivantes:

userid itemid strength 
4  5  6 

Et vous voulez cogner à la force = 9, utilisez ceci:

INSERT INTO table ON DUPLICATE KEY UPDATE VALUES(4,5,9) 

Il insérera une ligne avec 4,5,9 si elle n'existe pas, et mettra à jour la force à 9 sur la ligne avec la clé primaire (4,5) si elle existe. Il ne mettra à jour aucune autre ligne (par exemple, les lignes avec userid4 mais itemid 10 ou itemid 5 mais userid 70) car elles ne correspondent pas à la PK entière.

+0

techniquement c'est la clé primaire ou une clé unique –

1

Vous pouvez faire quelque chose comme ce qui suit (en supposant que votre ID utilisateur est dans la UserID variable et ID de l'élément est en ITEM_ID):

SELECT 
    @rowCount := COUNT(*) 
    FROM 
    table 
    WHERE 
    user_id = UserID 
    AND item_id = ItemID; 


    IF (@rowCount > 0) THEN 

    ... do update 

    ELSE 
    ... do insert 

    END IF; 
0

Pouvez-vous faire quelque chose comme

UPDATE TABLE 
set COL = 'BLAH BLAH' 
where ITEM_ID = @itemid AND USER_ID = @userid 

IF @@ROWCOUNT = 0 
BEGIN 
    INSERT INTO TABLE (col...) 
    VALUES (vals... 
END 
3

Je sais cette question est ancienne mais aucune des réponses n'est correcte.

Vous avez besoin d'un index PRIMARY or UNIQUE sur user_id et item_id (les deux colonnes d'un index).

Ensuite, vous pouvez utiliser "INSERT INTO ... VALUES ... ON DUPLICATE KEY UPDATE count=count+1" sans problème.

Ceci est EXACTLY ce que ON DUPLICATE UPDATE fera pour vous.

+0

Vieux, et je suis venu en 2015 pour la réponse - merci, utilisé avec UNIQUE, travaillé. – Setrino

Questions connexes