Philipp Hasenfratz: mysql_affected_rows zählt nicht richtig :-(

Beitrag lesen

Halihallo Sven und Theo

Also: Bei mysql_(p)connect als [client_flags] einfach die "2"
übergeben. Scheint bei dem genannten Autor funktioniert zu haben...

Ja, geht aber erst ab (IIRC) PHP Version 4.3.0. Wer das Pech hat, noch mit einer 4.2er oder älter zu arbeiten, und das nicht updaten kann, der hat Pech. Oder behilft sich damit, ein TIMESTAMP-Feld in die Tabelle zu packen und im UPDATE mit "NOW()" oder "NULL" zu füllen. Dann ändert sich immer was, und die Angabe ist wieder korrekt.

Jup. Wobei ich die Funktionalität nicht durch ein neues Attribut
gewährleisten würde (etwas viel Overhead); zugegeben, es ist die
einfachste und leider auch performanteste Lösung für alte PHP-
Versionen.

Dass CLIENT_FOUNT_ROWS per default "deaktiviert" ist, halte ich für
sinnvoll. Ein SELECT-Statement liefert für mysql_affected_rows genau
die Anzahl an Tupel, die auf die WHERE-Klause passen. Das macht
natürlich Sinn, denn genau diese sind die "Betroffenen Datensätze".
Was sind nun die "Betroffenen Datensätze" bei einem UPDATE? - Das
sind eben *nicht* jene, die auf WHERE "passen", sondern die, auf
die eine Aktion (UPDATE) ausgeführt wurde.

@Theo: Um trotz nichtgesetztem CLIENT_FOUND_ROWS an die "passenden"
(selektierten => SELECT) Tupel ranzukommen kannst du a) den Vorschlag
von Sven verfolgen, oder b) einfach einen SELECT vorschieben und dort
affected_rows auslesen. Dies braucht zwar Performance (zwei Queries),
ist jedoch (fast) "sauber". "Fast" deshalb, da du erst bei einem
TABLE LOCK sicherstellen kannst, dass sich zwischen den beiden
Queries nichts geändert hat.
Dann hättest du mehrere Informationen:
a) die passenden Einträge (SELECT's affected rows)
b) die geänderten Einträge (UPDATE's affected rows)
c) die gleich gebliebenen Einträge (Differenz der beiden obigen),
   die trotz UPDATE auf status quo blieben.

WICHTIG: Wie du siehst, ist affected_rows kein Beweis für die
korrekte Verarbeitung des Befehls. Falls du damit eine
Fehlerbehandlung implementieren möchtest, verwende (um Himmels
Willen) folgendes Konstrukt:

mysql_query(...) || die(mysql_error());
http://www.php.net/mysql_error
oder über Abfrage von
http://www.php.net/mysql_errno

so much for old PHP versions...

Viele Grüsse

Philipp