Zwiększenie wartości w zapytaniu aktualizującym mysql

139

Stworzyłem ten kod, aby dawać +1 punkt, ale nie działa poprawnie.

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

zmienna $ points jest punktami użytkownika w tej chwili .. Chcę, żeby to plus jeden do niego .. więc na przykład jeśli miał 5 punktów, to powinno być 5 + 1 = 6 .. ale tak nie jest, po prostu się zmienia do 1

Co zrobiłem źle? Dziękuję Ci

Karem
źródło
2
Miałem podobny problem, a potem zdałem sobie sprawę, że domyślny typ pola to „NULL”, zmieniłem go na 0 i wszystko było w porządku.
Azmeer

Odpowiedzi:

323

Możesz też po prostu zrobić to:

mysql_query("
    UPDATE member_profile 
    SET points = points + 1
    WHERE user_id = '".$userid."'
");
Tomas Markauskas
źródło
59
@Steve Twój komentarz może brzmieć sprytnie dla kogoś, kto wie, co to jest PDO, ale dla mnie, który właśnie zagłębia się w PHP / MySQL, nie rzuca to zbyt wiele światła na tę sprawę. Czy PDO sprawia, że ​​ten kod jest mniejszy lub bardziej elegancki? Jeśli tak, edytuj odpowiedź lub opublikuj własną, w której pokażesz, jak jest lepiej z PDO. Dzięki.
Camilo Martin
5
@CamiloMartin Też byłem zaciekawiony. Znalazłem to pomocne net.tutsplus.com/tutorials/php/ ...
PJ Brunet
11
@CamiloMartin Strona podręczników php.net dla mysql_query zawiera następującą notatkę: To rozszerzenie jest przestarzałe od PHP 5.5.0 i zostanie usunięte w przyszłości. Zamiast tego należy użyć rozszerzenia MySQLi lub PDO_MySQL . Zobacz także MySQL: wybór przewodnika po API i powiązanych często zadawanych pytań, aby uzyskać więcej informacji.
aland
9
Łączenie danych użytkownika, jak pokazano w zapytaniu SQL, jest głównym zagrożeniem dla iniekcji SQL.
trognanders
1
@bigp: Próbowałem UPDATE xyz SET points = MIN(points + 1, YOUR_LIMIT_VALUE_HERE)i nie udało się. Co nie działa to: UPDATE xyz SET points = points + 1 WHERE points < YOUR_LIMIT_VALUE_HERE.
Jealie
23

Możesz to zrobić bez konieczności sprawdzania rzeczywistej liczby punktów, dzięki czemu zaoszczędzisz czas i zasoby podczas wykonywania skryptu.

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

W przeciwnym razie źle robiłeś, że przekazałeś starą liczbę punktów jako string ( points='5'+1) i nie możesz dodać liczby do ciągu. ;)

Daan
źródło
10

Mam nadzieję, że nie przejdę do tematu offtopic w moim pierwszym poście, ale chciałbym trochę rozwinąć rzutowanie liczby całkowitej na łańcuch, ponieważ niektórzy respondenci wydają się mieć błąd.

Ponieważ wyrażenie w tym zapytaniu używa operatora arytmetycznego (symbol plusa +), MySQL skonwertuje wszystkie ciągi w wyrażeniu na liczby.

Aby zademonstrować, następujące wyniki dadzą wynik 6:

SELECT ' 05.05 '+'.95';

Konkatenacja ciągów w MySQL wymaga funkcji CONCAT (), więc nie ma tutaj dwuznaczności, a MySQL konwertuje ciągi znaków na zmiennoprzecinkowe i dodaje je razem.

Właściwie uważam, że powodem, dla którego początkowe zapytanie nie działało, jest najprawdopodobniej to, że zmienna $ points nie była w rzeczywistości ustawiona na bieżące punkty użytkownika. Było albo ustawione na zero, albo było nieustawione: MySQL wyrzuci pusty łańcuch na zero. Na przykład poniższe zwróci 0:

SELECT ABS('');

Tak jak powiedziałem, mam nadzieję, że nie jestem zbyt odbiegający od tematu. Zgadzam się, że Daan i Tomas mają najlepsze rozwiązania tego konkretnego problemu.

user272563
źródło
+1 compton bardzo dobre punkty, masz rację co do pracy obsady, czy są cytaty czy nie. Witamy w SO!
Pekka,
7
"UPDATE member_profile SET points = points + 1 WHERE user_id = '".$userid."'"
Mark Byers
źródło
1
co jeśli użyję zmiennej zamiast value = 1? czy powinienem to zrobić w ten sposób "punkty = punkty + $ zmienna"? lub „punkty = punkty + '$ zmienna'”
Ivo San
7

Ponadto, aby "zwiększyć" ciąg, podczas aktualizacji użyj CONCAT

update dbo.test set foo=CONCAT(foo, 'bar') where 1=1
bushkonst
źródło
3

Kto musi zaktualizować ciąg i liczby SET @a = 0; UPDATE obj_disposition SET CODE = CONCAT('CD_', @a:=@a+1);

Rodolfo Souza
źródło
2

Należy używać PDO, aby zapobiec ryzyku iniekcji SQL.

Możesz połączyć się z DB w ten sposób:

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');
}

Nie ma potrzeby wysyłania zapytań do bazy danych, aby uzyskać liczbę punktów. Możesz inkrementować bezpośrednio w zapytaniu aktualizującym ( points = points + 1).

(uwaga: również nie jest dobrym pomysłem zwiększanie wartości za pomocą PHP, ponieważ musisz najpierw wybrać dane, a wartość może ulec zmianie, jeśli inni użytkownicy ją zaktualizują).

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

$req->execute(array(
    'user_id' => $userid
));
Sébastien Gicquel
źródło
1

Usuń 'wokół point:

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

W pierwotnym zapytaniu „rzutujesz” wartość całkowitą na łańcuch ...

Amirshk
źródło
-2

Dlaczego nie pozwolisz PHP wykonać pracy?

"UPDATE member_profile SET points= ' ". ($points+1) ." '  WHERE user_id = '".$userid."'"
Petr Peller
źródło
7
Słuszna uwaga, ale zachowaj ostrożność w środowisku równoległym, ponieważ wartość DB mogła ulec zmianie w międzyczasie.
Vincent Nikkelen
1
Dzięki @VincentNikkelen, trafiłeś w sedno. Konkurencja!
Jimmy Ilenloa
1
W przypadku korzystania z tej metody należy najpierw WYBRAĆ dane, co oznacza dodatkowy dostęp do wiersza. To nie jest właściwa droga, jeśli musisz tylko zaktualizować wartość.
Andres SK,