在一个声明中插入IGNORE INTO和UPDATE

时间:2013-02-03 17:16:05

标签: php sql pdo

我正在运行一个脚本,为我的用户提供下载服务。我想在每个字节级别上监控它们的流量,并且我保留它们在$bytes中下载的字节数。我想将它记录到我的数据库,我正在使用以下功能:

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;
});

这个查询似乎工作一次,当下载完成时,表中有一条新记录,其中包含以下数据:

   date      |    bytes
------------------------
2013-02-03   |   2799469

但是,在每次其他下载时,bytes字段都不会更改。没有新记录,也没有对表中已有的记录进行更改。很明显问题是什么,查询尝试插入记录但如果它已经存在则会中止。我需要这样的更新声明:

UPDATE `stats`
SET `bytes` = `bytes` + :bytes
WHERE `date` = CURDATE()

但我想在一个查询中执行整个操作。如果记录不存在而且如果存在则创建记录的查询,则更新现有记录。

可以这样做,还是每次下载都需要运行两个查询?

1 个答案:

答案 0 :(得分:4)

您可能想要查看ON DUPLICATE KEY UPDATE。你可以阅读它here

您的查询看起来像这样。

$st = $db->prepare("INSERT INTO `STATS`
VALUES('CURDATE()', :bytes)
ON DUPLICATE KEY UPDATE `BYTES` = `BYTES` + :bytes");

您还应避免使用INSERT IGNORE INTO,因为如果行重复,则不会生成错误,只会生成警告。