I'm running a script which serves downloads to my users. I would like to monitor their traffic on a per byte level, and I hold how many bytes they've downloaded in $bytes. I want to log it to my database and I'm using the following function:
register_shutdown_function(function() {
global $bytes;
/* Save the traffic to the database */
$db = new PDO('mysql:host=localhost;dbname=test', 'root', '');
$st = $db->prepare('INSERT IGNORE INTO `stats`
SET `date` = CURDATE(), `bytes` = :bytes');
$st->bindParam(':bytes', $bytes);
$st->execute();
$st = null;
$db = null;
});
This query seems to work once, when the download is complete there's a new record in the table with the following data:
date | bytes
------------------------
2013-02-03 | 2799469
however, on every other download the bytes field doesn't change. No new records and no change to the record that's already in the table. It's pretty obvious what the problem is, the query tries to insert a record but if it already exists then it aborts. I need an update statement like this:
UPDATE `stats`
SET `bytes` = `bytes` + :bytes
WHERE `date` = CURDATE()
but I would like to do the entire operation in one query. A query that will create the record if it doesn't exist and if it does exist, update the existing record.
Can this be done or am I going to have to run two queries on every download?
You might want to look into ON DUPLICATE KEY UPDATE. You can read about it here.
Your query would look something like this.
$st = $db->prepare("INSERT INTO `STATS`
VALUES('CURDATE()', :bytes)
ON DUPLICATE KEY UPDATE `BYTES` = `BYTES` + :bytes");
You also should avoid using INSERT IGNORE INTO because in case of duplicate rows, no error will be generated, but only a warning.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With