PHP 8.4.1 Released!

mysqli::$affected_rows

mysqli_affected_rows

(PHP 5, PHP 7, PHP 8)

mysqli::$affected_rows -- mysqli_affected_rows Liefert die Anzahl der Datensätze, die vom letzten MySQL-Vorgang betroffen waren

Beschreibung

Objektorientierter Stil

Prozeduraler Stil

mysqli_affected_rows(mysqli $mysql): int|string

Gibt die Anzahl der von der letzten INSERT-, UPDATE-,REPLACE- oder DELETE-Abfrage betroffenen Datensätze zurück. Entspricht bei SELECT-Anweisungen mysqli_num_rows().

Parameter-Liste

mysql

Nur bei prozeduralem Aufruf: ein von mysqli_connect() oder mysqli_init() zurückgegebenes mysqli-Objekt.

Rückgabewerte

Eine Ganzzahl größer als Null zeigt die Anzahl der betroffenen oder abgerufenen Datensätze an. Null gibt an, dass bei einer UPDATE-Anweisung keine Datensätze aktualisiert wurden, keine Datensätze mit der WHERE-Klausel übereinstimmen oder dass die Datenbankabfrage noch nicht aufgeführt wurde. -1 gibt an, dass die Datenbankabfrage einen Fehler zurückgegeben hat oder dass mysqli_affected_rows() für eine ungepufferte SELECT-Abfrage aufgerufen wurde.

Hinweis:

Ist die Anzahl der betroffenen Datensätze größer als der maximale Integer-Wert (PHP_INT_MAX), wird die Anzahl der betroffenen Datensätze als Zeichenkette zurückgegeben.

Beispiele

Beispiel #1 $mysqli->affected_rows-Beispiel

Objektorientierter Stil

<?php

mysqli_report
(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
$mysqli = new mysqli("localhost", "my_user", "my_password", "world");

/* Datensätze einfügen */
$mysqli->query("CREATE TABLE Language SELECT * from CountryLanguage");
printf("Betroffene Datensätze (INSERT): %d\n", $mysqli->affected_rows);

$mysqli->query("ALTER TABLE Language ADD Status int default 0");

/* Datensätze ändern */
$mysqli->query("UPDATE Language SET Status=1 WHERE Percentage > 50");
printf("Betroffene Datensätze (UPDATE): %d\n", $mysqli->affected_rows);

/* Datensätze löschen */
$mysqli->query("DELETE FROM Language WHERE Percentage < 50");
printf("Betroffene Datensätze (DELETE): %d\n", $mysqli->affected_rows);

/* Alle Datensätze auswählen */
$result = $mysqli->query("SELECT CountryCode FROM Language");
printf("Betroffene Datensätze (SELECT): %d\n", $mysqli->affected_rows);

/* Tabelle Language löschen */
$mysqli->query("DROP TABLE Language");

Prozeduraler Stil

<?php

mysqli_report
(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
$link = mysqli_connect("localhost", "my_user", "my_password", "world");

/* Datensätze einfügen */
mysqli_query($link, "CREATE TABLE Language SELECT * from CountryLanguage");
printf("Betroffene Datensätze (INSERT): %d\n", mysqli_affected_rows($link));

mysqli_query($link, "ALTER TABLE Language ADD Status int default 0");

/* Datensätze ändern */
mysqli_query($link, "UPDATE Language SET Status=1 WHERE Percentage > 50");
printf("Betroffene Datensätze (UPDATE): %d\n", mysqli_affected_rows($link));

/* Datensätze löschen */
mysqli_query($link, "DELETE FROM Language WHERE Percentage < 50");
printf("Betroffene Datensätze (DELETE): %d\n", mysqli_affected_rows($link));

/* Alle Datensätze auswählen */
$result = mysqli_query($link, "SELECT CountryCode FROM Language");
printf("Betroffene Datensätze (SELECT): %d\n", mysqli_affected_rows($link));

/* Tabelle Language löschen */
mysqli_query($link, "DROP TABLE Language");

Die obigen Bespiele erzeugen folgende Ausgabe:

Betroffene Datensätze (INSERT): 984
Betroffene Datensätze (UPDATE): 168
Betroffene Datensätze (DELETE): 815
Betroffene Datensätze (SELECT): 169

Siehe auch

  • mysqli_num_rows() - Ermittelt die Anzahl der Zeilen einer Ergebnismenge
  • mysqli_info() - Ruft Informationen über die zuletzt ausgeführte Abfrage ab

add a note

User Contributed Notes 5 notes

up
47
Anonymous
13 years ago
On "INSERT INTO ON DUPLICATE KEY UPDATE" queries, though one may expect affected_rows to return only 0 or 1 per row on successful queries, it may in fact return 2.

From Mysql manual: "With ON DUPLICATE KEY UPDATE, the affected-rows value per row is 1 if the row is inserted as a new row and 2 if an existing row is updated."

See: http://dev.mysql.com/doc/refman/5.0/en/insert-on-duplicate.html

Here's the sum breakdown _per row_:
+0: a row wasn't updated or inserted (likely because the row already existed, but no field values were actually changed during the UPDATE)
+1: a row was inserted
+2: a row was updated
up
10
Jacques Amar
7 years ago
While using prepared statements, even if there is no result set (Like in an UPDATE or DELETE), you still need to store the results before affected_rows returns the actual number:

<?php
$del_stmt
->execute();
$del_stmt->store_result();
$count = $del_stmt->affected_rows;
?>

Otherwise things will just be frustrating ..
up
16
Michael
10 years ago
If you need to know specifically whether the WHERE condition of an UPDATE operation failed to match rows, or that simply no rows required updating you need to instead check mysqli::$info.

As this returns a string that requires parsing, you can use the following to convert the results into an associative array.

Object oriented style:

<?php
preg_match_all
('/(\S[^:]+): (\d+)/', $mysqli->info, $matches);
$info = array_combine ($matches[1], $matches[2]);
?>

Procedural style:

<?php
preg_match_all
('/(\S[^:]+): (\d+)/', mysqli_info ($link), $matches);
$info = array_combine ($matches[1], $matches[2]);
?>

You can then use the array to test for the different conditions

<?php
if ($info ['Rows matched'] == 0) {
echo
"This operation did not match any rows.\n";
} elseif (
$info ['Changed'] == 0) {
echo
"This operation matched rows, but none required updating.\n";
}

if (
$info ['Changed'] < $info ['Rows matched']) {
echo (
$info ['Rows matched'] - $info ['Changed'])." rows matched but were not changed.\n";
}
?>

This approach can be used with any query that mysqli::$info supports (INSERT INTO, LOAD DATA, ALTER TABLE, and UPDATE), for other any queries it returns an empty array.

For any UPDATE operation the array returned will have the following elements:

Array
(
[Rows matched] => 1
[Changed] => 0
[Warnings] => 0
)
up
0
mishell dot mercer at gmail dot com
3 months ago
Do note that if you have turned off autocommit, and plan to do multiple actions before the commit, $affected_rows only works per statement. This means if, for example, you want to run multiple INSERT statements and tally all rows inserted after they are commited, a running counter will need to be implemented.

// start the count
$count = 0;

// turn off autocommit
$mysqli->autocommit(FALSE);
$mysqli->begin_transaction;

// insert a couple items
$query = "
INSERT INTO users ('id','username','email')
VALUES (1, 'userguy', 'userguy@mail.com'), (2, 'some_user', 'some_user@ymail.com')
";
$mysqli->query($query);
echo $mysqli->affected_rows; // 2 - correct
$count += $mysqli->affected_rows; // add to the count

// insert one more
$query = "
INSERT INTO users ('id','username','email')
VALUES (3, 'anotherone', 'anotherone@mail.com')
";
$mysqli->query($query);
$count += $mysqli->affected_rows;

// insert one more
$query = "
INSERT INTO users ('id','username','email')
VALUES (4, 'thefourth', 'thefourth@gmail.com')
";
$mysqli->query($query);
$count += $mysqli->affected_rows;

// commit these statements to the database
$mysqli->commit();

echo $mysqli->affected_rows; // 1 - only counts the last statement run
echo "Actual count: ".$count; // 4
up
-3
lucgommans.nl
1 year ago
Under the hood, this calls into mysql_affected_rows (1). The MariaDB function ROW_COUNT() mentions (2) that it is the equivalent of that C API function. These two lines, SQL followed by PHP, should be equivalent:

SELECT ROW_COUNT();
$db->affected_rows;

I found this useful to double check things in an SQL prompt, to make sure affected_rows is reflecting what I expect (changed rows as opposed to matched rows in an update statement), which indeed it did.

1. https://github.com/php/php-src/blob/1521cafee29e23ca147ec777f3770a7ac46c6880/ext/mysqli/mysqli_api.c#L36-L49
2. https://mariadb.com/kb/en/row_count/
To Top