我正在运行一个脚本,为我的用户提供下载服务。我想在每字节的级别上监控他们的流量,并保存他们在$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()
但我想在一个查询中完成整个操作。如果记录不存在,将创建该记录的查询;如果记录确实存在,则更新现有记录。
可以这样做吗?还是每次下载都要运行两个查询?
您可能需要了解ON DUPLICATE KEY UPDATE
。你可以在这里阅读。
您的查询看起来像这样。
$st = $db->prepare("INSERT INTO `STATS`
VALUES('CURDATE()', :bytes)
ON DUPLICATE KEY UPDATE `BYTES` = `BYTES` + :bytes");
您还应该避免使用INSERT IGNORE INTO
,因为在重复行的情况下,不会生成任何错误,而只是一个警告。