【问题标题】:INSERT IGNORE INTO and UPDATE in one statement在一个语句中插入 IGNORE INTO 和 UPDATE
【发布时间】:2013-02-03 17:16:05
【问题描述】:

我正在运行一个为我的用户提供下载的脚本。我想在每个字节级别监控他们的流量,我保存他们在$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()

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

这可以做到吗,还是我每次下载都必须运行两个查询?

【问题讨论】:

    标签: php sql pdo


    【解决方案1】:

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

    您的查询将如下所示。

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

    你也应该避免使用INSERT IGNORE INTO,因为在重复行的情况下,不会产生错误,只会产生警告。

    【讨论】:

    • 谢谢,但是该查询出现 SQL 错误。就是说SET bytes`=bytes+1024`附近有错误
    • 这看起来像是一个放错引号的情况。
    • 我看不到...所有引号都有结尾引号:/ pastebin.com/CqPKTZwz
    • 编辑:找到问题了,应该是ON DUPLICATE KEY UPDATE BYTES` = BYTES + :bytes"), not SET`。谢谢!
    • 好了,是时候去复习我自己的 SQL 了。反映了答案的变化。
    猜你喜欢
    • 2020-10-14
    • 1970-01-01
    • 1970-01-01
    • 2013-07-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多