質問

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

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top