Reputation: 26301
Consider the following three queries.
The first one can only return a single row as bids_buy.id
is the primary key.
The second one shows an existing record in entities_has_documents
for primary key 3099541982-2536988132
, and the third one doesn't execute due to that existing record.
The forth one does execute as expected, but shows two affected rows.
Why does it show two affected rows, and not just one associated with primary key 3099541982-2536988132
?
mysql> SELECT bb.bids_sell_id, 2536988132,"pub_bids", NOW(),506836355 FROM bids_buy bb WHERE bb.id=2453409798;
+--------------+------------+----------+---------------------+-----------+
| bids_sell_id | 2536988132 | pub_bids | NOW() | 506836355 |
+--------------+------------+----------+---------------------+-----------+
| 3099541982 | 2536988132 | pub_bids | 2016-04-16 08:19:13 | 506836355 |
+--------------+------------+----------+---------------------+-----------+
1 row in set (0.00 sec)
mysql> SELECT * FROM entities_has_documents;
+-------------+--------------+----------+---------------------+--------------+-----------+------------+-----------+-------------+
| entities_id | documents_id | type | date_added | date_removed | added_by | removed_by | purged_by | date_purged |
+-------------+--------------+----------+---------------------+--------------+-----------+------------+-----------+-------------+
| 2453409798 | 2536988132 | pub_bids | 2016-04-16 08:07:13 | NULL | 506836355 | NULL | NULL | NULL |
| 3099541982 | 2536988132 | pub_bids | 2016-04-16 08:18:53 | NULL | 506836355 | NULL | NULL | NULL |
+-------------+--------------+----------+---------------------+--------------+-----------+------------+-----------+-------------+
2 rows in set (0.00 sec)
mysql> INSERT INTO entities_has_documents(entities_id,documents_id,type,date_added,added_by)
-> SELECT bb.bids_sell_id, 2536988132,"pub_bids", NOW(),506836355 FROM bids_buy bb WHERE bb.id=2453409798;
ERROR 1062 (23000): Duplicate entry '3099541982-2536988132' for key 'PRIMARY'
mysql> INSERT INTO entities_has_documents(entities_id,documents_id,type,date_added,added_by)
-> SELECT bb.bids_sell_id, 2536988132,"pub_bids", NOW(),506836355 FROM bids_buy bb WHERE bb.id=2453409798
-> ON DUPLICATE KEY UPDATE type="pub_bids", added_by=506836355, date_added=NOW(), removed_by=NULL, date_removed=NULL;
Query OK, 2 rows affected (0.00 sec)
Records: 1 Duplicates: 1 Warnings: 0
mysql> EXPLAIN bids_buy;
+--------------+------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+--------------+------------------+------+-----+---------+-------+
| id | int(10) unsigned | NO | PRI | NULL | |
| bids_sell_id | int(10) unsigned | NO | MUL | NULL | |
| stage_buy_id | int(10) unsigned | NO | MUL | NULL | |
+--------------+------------------+------+-----+---------+-------+
3 rows in set (0.01 sec)
mysql> EXPLAIN entities_has_documents;
+--------------+------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+--------------+------------------+------+-----+---------+-------+
| entities_id | int(10) unsigned | NO | PRI | NULL | |
| documents_id | int(10) unsigned | NO | PRI | NULL | |
| type | varchar(16) | NO | MUL | NULL | |
| date_added | datetime | NO | | NULL | |
| date_removed | datetime | YES | | NULL | |
| added_by | int(10) unsigned | NO | MUL | NULL | |
| removed_by | int(10) unsigned | YES | MUL | NULL | |
| purged_by | int(10) unsigned | YES | MUL | NULL | |
| date_purged | datetime | YES | | NULL | |
+--------------+------------------+------+-----+---------+-------+
9 rows in set (0.01 sec)
mysql>
EDIT
Per http://php.net/manual/en/pdostatement.rowcount.php
If the last SQL statement executed by the associated PDOStatement was a SELECT statement, some databases may return the number of rows returned by that statement. However, this behaviour is not guaranteed for all databases and should not be relied on for portable applications.
So, am I just seeing the number or rows returned from my SELECT statement, and not the number or rows affected by my INSERT? Why would MySQL do such a thing?
EDIT DONE
Upvotes: 2
Views: 2585
Reputation: 5016
I think it is due to ON DUPLICATE KEY UPDATE
modifier as the MYSQL Reference Manual 5.5 as well as MySQL Reference Manual 5.7 says
If you specify ON DUPLICATE KEY UPDATE, and a row is inserted that would cause a duplicate value in a UNIQUE index or PRIMARY KEY, an UPDATE of the old row is performed. 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 to mysql_real_connect() when connecting to mysqld, the affected-rows value is 1 (not 0) if an existing row is set to its current values.”.
In your case you already had a row with primary key value 3099541982-2536988132
. Hence the MySQL lets you know that you are trying to insert a row with duplicate Primary or Unique key by indicating 2 rows affected. As the manual also say that ON DUPLICATE KEY UPDATE
leads to the sequence of INSERT
than UPDATE
update command in case of duplicate key whereas it executes only the INSERT
command in case the key is not present.
I hope this helps.
UPDATE
Also see this link.
Upvotes: 4