Incrémenter la valeur dans la requête de mise à jour mysql

140

J'ai créé ce code pour donner +1 point, mais cela ne fonctionne pas correctement.

mysql_query("
    UPDATE member_profile 
    SET points= ' ".$points." ' + 1 
    WHERE user_id = '".$userid."'
");

la variable $ points est les points de l'utilisateur en ce moment .. Je veux qu'il y ajoute un .. donc par exemple s'il avait 5 points, ça devrait être 5 + 1 = 6 .. mais ça ne marche pas, ça change juste à 1

Qu'est ce que j'ai mal fait? Merci

Karem
la source
2
J'ai eu un problème similaire, puis j'ai réalisé que le type par défaut du champ était «NULL», je l'ai changé en 0 et tout allait bien.
Azmeer

Réponses:

324

Vous pouvez également faire ceci:

mysql_query("
    UPDATE member_profile 
    SET points = points + 1
    WHERE user_id = '".$userid."'
");
Tomas Markauskas
la source
59
@Steve votre commentaire peut sembler intelligent pour quelqu'un qui sait ce qu'est PDO, mais pour moi qui ne fais que plonger dans PHP / MySQL, cela n'éclaire pas vraiment beaucoup de lumière. PDO rend-il ce code plus petit ou plus élégant? Si tel est le cas, veuillez modifier la réponse ou publier l'une des vôtres où vous montrez comment c'est mieux avec PDO. Merci.
Camilo Martin
5
@CamiloMartin J'étais aussi curieux. J'ai trouvé cela utile net.tutsplus.com/tutorials/php/…
PJ Brunet
11
@CamiloMartin la page des manuels php.net pour mysql_query a la note suivante: Cette extension est obsolète à partir de PHP 5.5.0, et sera supprimée dans le futur. A la place, l' extension MySQLi ou PDO_MySQL doit être utilisée. Voir aussi MySQL: choisir un guide d' API et la FAQ associée pour plus d'informations.
aland
9
La concaténation des données utilisateur comme démontré dans une requête SQL est un risque majeur d'injection SQL.
trognanders
1
@bigp: J'ai essayé UPDATE xyz SET points = MIN(points + 1, YOUR_LIMIT_VALUE_HERE)et cela n'a pas fonctionné. Qu'est-ce que le travail était: UPDATE xyz SET points = points + 1 WHERE points < YOUR_LIMIT_VALUE_HERE.
Jealie
23

Vous pouvez le faire sans avoir à interroger le nombre réel de points, ce qui vous fera gagner du temps et des ressources lors de l'exécution du script.

mysql_query("UPDATE `member_profile` SET `points`= `points` + 1 WHERE `user_id` = '".intval($userid)."'");

Sinon, ce que vous faisiez mal, c'est que vous avez passé l'ancien nombre de points sous forme de chaîne ( points='5'+1), et vous ne pouvez pas ajouter un nombre à une chaîne. ;)

Daan
la source
10

J'espère que je ne vais pas sortir du sujet lors de mon premier message, mais j'aimerais développer un peu le casting d'entier en chaîne car certains répondants semblent l'avoir mal.

Étant donné que l'expression de cette requête utilise un opérateur arithmétique (le symbole plus +), MySQL convertira toutes les chaînes de l'expression en nombres.

Pour démontrer, ce qui suit produira le résultat 6:

SELECT ' 05.05 '+'.95';

La concaténation de chaînes dans MySQL nécessite la fonction CONCAT () donc il n'y a pas d'ambiguïté ici et MySQL convertit les chaînes en flottants et les ajoute ensemble.

Je pense en fait que la raison pour laquelle la requête initiale ne fonctionnait pas est très probablement parce que la variable $ points n'était en fait pas définie sur les points actuels de l'utilisateur. Il était soit mis à zéro, soit non défini: MySQL convertira une chaîne vide à zéro. À titre d'illustration, ce qui suit renverra 0:

SELECT ABS('');

Comme je l'ai dit, j'espère que je ne suis pas trop hors sujet. Je conviens que Daan et Tomas ont les meilleures solutions pour ce problème particulier.

utilisateur272563
la source
+1 compton très bons points, vous avez raison sur le travail du casting, qu'il y ait des citations ou non. Bienvenue à SO!
Pekka
7
"UPDATE member_profile SET points = points + 1 WHERE user_id = '".$userid."'"
Mark Byers
la source
1
Et si j'utilisais une variable au lieu de value = 1? dois-je le faire de cette façon "points = points + $ variable"? ou "points = points + '$ variable'"
Ivo San
7

De plus, pour "incrémenter" la chaîne, lors de la mise à jour, utilisez CONCAT

update dbo.test set foo=CONCAT(foo, 'bar') where 1=1
Bushkonst
la source
3

Qui a besoin de mettre à jour la chaîne et les nombres SET @a = 0; UPDATE obj_disposition SET CODE = CONCAT('CD_', @a:=@a+1);

Rodolfo Souza
la source
2

Vous devez utiliser PDO pour éviter les risques d'injection SQL.

Vous pouvez vous connecter à DB comme ceci:

try {
    $pdo_options[PDO::ATTR_ERRMODE] = PDO::ERRMODE_EXCEPTION;
    $bdd = new PDO('mysql:host=xxxx;dbname=xxxx', 'user', 'password', $pdo_options);
    $bdd->query('SET NAMES "utf8"');
} catch (PDOException $e) {
    exit('Error');
}

Pas besoin d'interroger DB pour obtenir le nombre de points. Vous pouvez incrémenter directement dans la requête de mise à jour (points = points + 1 ).

(Remarque: De plus, ce n'est pas une bonne idée d'incrémenter la valeur avec PHP car vous devez d'abord sélectionner les données et la valeur peut changer si d'autres utilisateurs la mettent à jour.)

$req = $bdd->prepare('UPDATE member_profile SET 
            points = points + 1
            WHERE user_id = :user_id');

$req->execute(array(
    'user_id' => $userid
));
Sébastien Gicquel
la source
1

Retirez le 'autour du point:

mysql_query("UPDATE member_profile SET points=".$points."+1 WHERE user_id = '".$userid."'");

Vous «convertissez» une valeur entière en chaîne dans votre requête d'origine ...

Amirshk
la source
-2

Pourquoi ne laissez-vous pas PHP faire le travail?

"UPDATE member_profile SET points= ' ". ($points+1) ." '  WHERE user_id = '".$userid."'"
Petr Peller
la source
7
Bon point, mais soyez prudent dans un environnement concurrent car la valeur de la base de données peut avoir changé entre-temps.
Vincent Nikkelen
1
Merci @VincentNikkelen, vous avez frappé dans le mille. Concurrence!
Jimmy Ilenloa
1
Si vous utilisez cette méthode, vous devez d'abord SELECT les données, ce qui signifie un accès supplémentaire à la ligne. Ce n'est pas la voie à suivre si vous avez juste besoin de mettre à jour la valeur.
Andres SK