3

ユーザーにダウンロードを提供するスクリプトを実行しています。バイトレベルでトラフィックを監視したいのですが、ダウンロードしたバイト数を保持しています$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つのクエリで実行したいと思います。レコードが存在しない場合はレコードを作成し、存在する場合は既存のレコードを更新するクエリ。

これを実行できますか、それともダウンロードごとに2つのクエリを実行する必要がありますか?

4

1 に答える 1

4

を調べてみてくださいON DUPLICATE KEY UPDATE。あなたはここでそれについて読むことができます。

クエリは次のようになります。

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

INSERT IGNORE INTOまた、行が重複している場合、エラーは生成されず、警告のみが生成されるため、使用は避けてください。

于 2013-02-03T17:23:18.637 に答える