I've accomplished what you're describing using a while loop so that each iteration creates a MySQL statement that affects one row. Within the loop, I run the mysql_affected_rows() and then increment a counter depending upon whether the value returned was a 0 or a 1. At the end of the loop, I echo both variables for viewing.
The complete wording from MySQL Docs regarding the mysql_affected_rows function is (notice there are 3 possible values returned - 0, 1, or 2):
For INSERT ... ON DUPLICATE KEY UPDATE statements, the affected-rows
value per row is 1 if the row is inserted as a new row, 2 if an
existing row is updated, and 0 if an existing row is set to its
current values. If you specify the CLIENT_FOUND_ROWS flag, the
affected-rows value is 1 (not 0) if an existing row is set to its
current values.
(Sidenote - I set $countUpdate and $countInsert and $countUpdateNoChange to 0 prior to the while loop):
Here's the code that I developed that works great for me:
while (conditions...) {
$sql = "INSERT INTO test_table (control_number, name) VALUES ('123', 'Bob')
ON DUPLICATE KEY UPDATE name = 'Bob'";
mysql_query($sql) OR die('Error: '. mysql_error());
$recordModType = mysql_affected_rows();
if ($recordModType == 0) {
$countUpdateNoChange++;
}elseif($recordModType == 1){
$countInsert++;
}elseif($recordModType == 2){
$countUpdate++;
};
};
echo $countInsert." rows inserted<br>";
echo $countUpdateNoChange." rows updated but no data affected<br>";
echo $countUpdate." rows updated with new data<br><br>";
Hopefully, I haven't made any typos as I've recreated it to share while removing my confidential data.
Hope this helps someone. Good luck coding!