Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

INSERT IGNORE INTO and UPDATE in one statement

Tags:

sql

php

pdo

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?

like image 686
James Dawson Avatar asked Dec 31 '25 10:12

James Dawson


1 Answers

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.

like image 163
Achrome Avatar answered Jan 01 '26 23:01

Achrome