2011-09-16 6 views
24

Próbowałem znaleźć odpowiedź na to pytanie, ale nie znalazłem żadnego ostatecznego "tak" lub "nie" we wszystkich moich badaniach.Uzyskaj zaktualizowaną wartość w MySQL zamiast zaatakowanych wierszy

biegnę proste zapytanie MySQL tak:

UPDATE item SET `score`=`score`+1 WHERE `id`=1 

Czy istnieje sposób dla tego zapytania, aby powrócić zaktualizowaną wartość, zamiast liczby wierszy dotyczy? Tylko jako punkt odniesienia, robię to w PHP, więc rzeczywisty kod wygląda następująco:

$sql = "UPDATE item SET `score`=`score`+1 WHERE `id`=1"; 
$new_value = mysql_query($sql); 
//Unfortunately this does not return the new value 

Wiem, że mógłbym zrobić drugą kwerendę i po prostu wybrać odpowiednią wartość, ale staram się obniżyć zapytań w miarę możliwości. Czy istnieje sposób?

+0

Nie, nie sądzę, że istnieje. –

Odpowiedz

22

Można to zrobić za pomocą procedury składowanej, która aktualizuje, a następnie wybiera nową wartość do parametru wyjściowego. Następująca zwraca jedną kolumnę new_score z nową wartością.

DELIMITER $$ -- Change DELIMITER in order to use ; withn the procedure 
CREATE PROCEDURE increment_score 
(
    IN id_in INT 
) 
BEGIN 
    UPDATE item SET score = score + 1 WHERE id = id_in; 
    SELECT score AS new_score FROM item WHERE id = id_in; 
END 
$$   -- Finish CREATE PROCEDURE statement 
DELIMITER ; -- Reset DELIMITER to standard ; 

W PHP:

$result = mysql_query("CALL increment_score($id)"); 
$row = mysql_fetch_array($result); 
echo $row['new_score']; 
+1

Czy wydajność wykonywania tej operacji w procedurze przechowywanej jest lepsza niż wykonywanie dwóch zapytań SQL? – jwegner

+0

@jwegner Wydajność prawdopodobnie będzie trochę lepsza, ponieważ RDBMS nie musi analizować żadnego z zapytań. Oba są już skompilowane w procedurze po stronie RDBMS. –

+2

@jwegner Benchmark to jest jednak pewne ... –

10

Nie, w MySQL nie ma nic podobnego od UPDATE ... RETURNING output_expression Postgresql (jeszcze?).

+3

Naprawdę nie pomaga w przypadku pytania (jeśli rzeczywiście istnieje odpowiedź), ale +1 za interesującą informację! –

0

Nie możesz. Można utworzyć funkcję lub procedurę składowaną, która może wykonać wstawkę i zwrócić zaktualizowaną wartość, ale to nadal wymagałoby wykonania dwóch zapytań z funkcji lub procedury składowanej.

-1

Można utworzyć wyzwalacz, a będziesz wiedzieć wszystko o modyfikacjach.

1

Jeśli nie chcesz uruchamiać kolejnej kwerendy SELECT, to tutaj jest inny sposób na zrobienie tego. Zmodyfikowałem kod pana Berkowskiego dla odniesienia:

DELIMITER $$ 
CREATE PROCEDURE increment_score 
(
    IN id_in INT 
) 
BEGIN 
    set @newScore := null; 
    UPDATE item SET score = IF((@newScore := score+1) <> NULL IS NULL, @newScore, NULL) WHERE id = id_in; 
    SELECT @newScore; 
END 
DELIMITER ;