The 5th Annual China PHP Conference


(PHP 4, PHP 5)

mysql_affected_rowsObtiene el número de filas afectadas en la anterior operación de MySQL


Esta extensión fue declarada obsoleta en PHP 5.5.0 y eliminada en PHP 7.0.0. En su lugar debería utilzarse las extensiones MySQLi o PDO_MySQL. Véase también la guía MySQL: elegir una API y sus P+F relacionadas para más información. Alternatives to this function include:


int mysql_affected_rows ([ resource $link_identifier = NULL ] )

Obtiene el número de filas afectadas por la última consulta INSERT, UPDATE, REPLACE o DELETE asociada con link_identifier.



La conexión MySQL. Si no se especifica el identificador de enlace, se asume el último enlace abierto por mysql_connect(). Si no se encuentra este enlace, se intentará crear un nuevo enlace como si mysql_connect() hubiese sido invocada sin argumentos. Si no se encuentra o establece ninguna conexión, se genera un error de nivel E_WARNING.

Valores devueltos

Devuelve el número de filas afectadas en caso de éxito, y -1 si la última consulta falló.

Si la consulta anterior fue DELETE con ninguna cláusula WHERE, todos los registros habrán sido borrados de la tabla, aunque ésta función devolverá cero con una versión anterior a MySQL 4.1.2.

Al utilizar UPDATE, MySQL no actualiza las columnas donde el nuevo valor es el mismo que el anterior. Esto crea la posibilidad de que mysql_affected_rows() no pueda equivaler en realidad al número de filas encontradas, solamente el número de filas que estuvieron literalmente afectadas por la consulta.

La sentencia REPLACE primero borra el registro con la misma clave primaria y luego inserta el nuevo registro. Esta función devuelve el número de registros borrados más el número de registros insertados.

En el caso de consultas "INSERT ... ON DUPLICATE KEY UPDATE", el valor devuelto será 1 si se realizó una inserción, o 2 para una actualización de una fila existente.


Ejemplo #1 Ejemplo de mysql_affected_rows()

if (!
$enlace) {
'No se pudo conectar: ' mysql_error());

/* Esto debería devolver el número correcto de registros borrados */
mysql_query('DELETE FROM mitabla WHERE id < 10');
printf("Registros borrados: %d\n"mysql_affected_rows());

/* con una clausula WHERE que nunca es verdad, debería devolver 0 */
mysql_query('DELETE FROM mitabla WHERE 0');
printf("Registros borrados: %d\n"mysql_affected_rows());

El resultado del ejemplo sería algo similar a:

Registros borrados: 10
Registros borrados: 0

Ejemplo #2 Ejemplo de mysql_affected_rows() al utilizar transacciones

if (!
$enlace) {
'No se pudo conectar: ' mysql_error());

/* Actualizar registros */
mysql_query("UPDATE mitabla SET usado=1 WHERE id < 10");
printf ("Registros actualizados: %d\n"mysql_affected_rows());

El resultado del ejemplo sería algo similar a:

Registros actualizados: 10


Nota: Transacciones

Si se usan transacciones, es necesario llamar a mysql_affected_rows() después de una consulta INSERT, UPDATE, o DELETE, no después del COMMIT.

Nota: Sentencias SELECT

Para conocer el número de filas devueltas por un SELECT, es posible usar mysql_num_rows().

Nota: Claves Foráneas en Cascada

mysql_affected_rows() no cuenta la filas afectadas implícitamente a través del uso de ON DELETE CASCADE y/o ON UPDATE CASCADE en las restricciones de las claves foráneas.

Ver también

  • mysql_num_rows() - Obtener el número de filas de un conjunto de resultados
  • mysql_info() - Obtiene información sobre la consulta más reciente

add a note add a note

User Contributed Notes 10 notes

dobrys at abv dot bg
9 years ago
I see that when try to use mysql_affected_rows() with "mysql_pconnect(...)" without link indetifier as param in "mysql_affected_rows()" the result is allways -1.
When use link identifier "mysql_affected_rows($this_sql_connection)" - everything is Fine. This is is on PHP Version 5.2.0
Hope that this was helpfull for somebody
9 years ago
If you use "INSERT INTO ... ON DUPLICATE KEY UPDATE" syntax, mysql_affected_rows() will return you 2 if the UPDATE was made (just as it does with the "REPLACE INTO" syntax) and 1 if the INSERT was.

So if you use one SQL request to insert several rows at a time, and some are inserted, some are just updated, you won't get the real count.
temp02 at flexis dot com dot br
11 years ago
1. You're using MySQL 4.1x with foreign keys.
2. You have table t2 linked to table t1 by a CASCADE ON DELETE foreign key.
3. t2 has a UNIQUE key so that duplicate records are unacceptable.
3. You have a REPLACE query on t1 followed by an INSERT query on t2 and expect the second query to fail if there's an attempted insert of a duplicate record.

You notice that the second query is not failing as you had expected even though the record being inserted is an exact duplicate of a record previously inserted.

When the first query (the REPLACE query) deletes a record from t1 in the first stage of the REPLACE operation, it cascades the delete to the record that would be duplicated in t2. The second query then does not fail because the "duplicate" record is no longer a duplicate, as the original one has just been deleted.
vitospericolato at gmail dot com
4 months ago
calling mysql_affected_rows(null)
is not the same that calling mysql_affected_rows()

So, if you have a $link variable that could be null, you must write

1 year ago
I was just testing  "INSERT INTO ... ON DUPLICATE KEY UPDATE" syntax, on PHP 5.3.29 and mysql_affected_rows() was returning either 2 for updated row, 1 for inserted new row, and also 0, which was not documented, evidently when nothing was inserted. I was inserting a single row.
Ome Ko
5 years ago
There are no rows affected by an update with identical data.
So here is one very ugly solution for these cases:
function mysql_matched_rows() {
$_kaBoom=explode(' ',mysql_info());
brian at smitherconsulting dot com
6 months ago
In the case of INSERT where a row/slot had been previously deleted, making an uncollapsed hole in the table, and the record being inserted fills that empty row/slot, that is to say, the inserted data did not create a new row/slot/space, then this may explain why a zero result is returned by this function.
deponti A_T tiscalinet D0T it
13 years ago
It works also for REPLACE query,returning:
0 if the record it's already updated (0 record modified),
1 if the record it's new (1 record inserted),
2 if the record it's updated (2 operations: 1 deletion+ 1 insertion)
sean at adtools dot co dot uk
8 years ago
Here's a little function I've been using for a while now, pass it two parameters (action command (1 or 0 see notes)) and a sql statement.

It returns a simple line which shows the length of time taken to action the query, the status of the query (0= query not actioned, you can set this value for testing, 1=success qry executed successfully, -1= failed, there was a problem with the sql statement) the number of lines affected by that query and the sql statement itself.

I've found this invaluable when trying to tie down large amounts of updates to a table, using this you can easily see where a query was successfully executed and the number of rows are affected, or where there are problems and a statement has failed for example.

function dosql($action,$sql){
# assuming you have setup a link to your database entitled $link
  # action = 1 run this query
  # action = 0 don't run, just return sql statement
$start = getmtime();
$result = mysql_query($sql);
$affectedrows = "[".mysql_affected_rows($link)."]";
"[".number_format((getmtime()-$start),3)."][$action]: $sql\n";

Example output:
[0.072][1][80]: UPDATE MYTABLE SET FIELD = 1;

The output shows:

[Timetaken][result]][lines affected]

The result will be either -1, 0 or 1, -1 means there's a problem with the sql statement, 1 means it executed correctly, 0 means it wasn't executed.
steffen at showsource dot dk
12 years ago
Using OPTIMIZE TABLE will also return true.
So, if you want to check the numbers of deleted records, use mysql_affected_rows() before OPTIMIZE TABLE
To Top