I have a statement that tries to insert a record and if it already exists, it simply updates the record.
INSERT INTO temptable (col1,col2,col3)
VALUES (1,2,3)
ON DUPLICATE KEY UPDATE col1=VALUES(col1), col2=VALUES(col2), col3=VALUES(col3);
The full statement has multiple inserts and I'm looking to count number of INSERTs against the UPDATEs. Can I do this with MySQL variables, I've yet to find a way to do this after searching.
From Mysql Docs
In the case of "INSERT ... ON DUPLICATE KEY UPDATE" queries, the return value will be 1 if an insert was performed, or 2 for an update of an existing row.
Use mysql_affected_rows()
after your query, if INSERT
was performed it will give you 1
and if UPDATE
was performed it will give you 2
.
I know this is a bit old, but I was doing a bulk insert in PHP and needed to know exactly how many rows were inserted and updated (separately).
So I used this:
$dataCount = count($arrData); // number of rows in the statement
$affected = mysql_affected_rows(); // mysqli_*, PDO's rowCount() or anything
$updated = $affected - $dataCount;
$inserted = 2 * $dataCount - $affected;
Simple trace table:
-------------------------------
| data | affected | ins | upd |
-------------------------------
| 1 | 1 | 1 | 0 |
-------------------------------
| 2 | 2 | 2 | 0 |
| 2 | 3 | 1 | 1 |
| 2 | 4 | 0 | 2 |
-------------------------------
| 3 | 3 | 3 | 0 |
| 3 | 4 | 2 | 1 |
| 3 | 5 | 1 | 2 |
| 3 | 6 | 0 | 3 |
-------------------------------
| 4 | 4 | 4 | 0 |
| 4 | 5 | 3 | 1 |
| 4 | 6 | 2 | 2 |
| 4 | 7 | 1 | 3 |
| 4 | 8 | 0 | 4 |
-------------------------------
| 5 | 5 | 5 | 0 |
| 5 | 6 | 4 | 1 |
| 5 | 7 | 3 | 2 |
| 5 | 8 | 2 | 3 |
| 5 | 9 | 1 | 4 |
| 5 | 10 | 0 | 5 |
-------------------------------
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!
if you want to get the number of records that have been inserted and updated separetly, you are to issue each statement separetly.
You should use mysql_affected_rows()
just after your query.
http://dev.mysql.com/doc/refman/5.1/en/mysql-affected-rows.html