2011-09-16 9 views
24

He estado tratando de encontrar una respuesta a esta pregunta, pero no he encontrado ningún "sí" o un "no" definitivo en todas mis investigaciones.Obtener valor actualizado en MySQL en lugar de filas afectadas

estoy corriendo un simple consulta MySQL como esto:

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

¿Hay alguna manera de esa consulta para devolver el valor actualizado, en lugar del número de filas afectadas? Sólo como referencia, que estoy haciendo esto en PHP, por lo que el código real se parece a:

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

Sé que podría hacer una segunda consulta y simplemente seleccionar el valor, pero estoy tratando de reducir consultas tanto como sea posible. ¿Hay alguna manera?

+0

No, no creo que exista. –

Respuesta

22

Puede hacerlo con un procedimiento almacenado que se actualiza y luego selecciona el nuevo valor en un parámetro de salida. Lo siguiente devuelve una columna new_score con el nuevo valor.

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 ; 

En PHP:

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

¿El rendimiento de hacer esto en un procedimiento almacenado es mejor que solo hacer dos consultas SQL? – jwegner

+0

@jwegner El rendimiento probablemente será un poco mejor porque el RDBMS no tiene que analizar ninguna de las consultas. Ambos ya están compilados en el procedimiento en el lado RDBMS. –

+2

@jwegner Benchmark it para estar seguro aunque ... –

0

No, no puedes. Podría hacer una función o procedimiento almacenado que podría hacer la inserción y devolver el valor actualizado, pero eso aún requeriría que ejecute dos consultas desde la función o el procedimiento almacenado.

-1

Usted puede crear un disparador, y sabrá todo sobre las modificaciones.

1

Si no desea ejecutar otro Query SELECT, esta es otra forma de hacerlo. He modificado el código del señor Berkowski como referencia:

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 ; 
Cuestiones relacionadas