gologiusの巣

プログラミングなどの技術メモです。誰かの役に立てるとうれしいです。

PHP+SQLiteで、UPDATE文を実行すると、エラーを吐かずになぜか0 がセットされる

総括

SQLiteにおいて、SQLの書き方によっては文法エラーにならずに、 意図しない値がDBにセットされる模様。

※見解が間違っていたらごめんなさいm( "m)

背景

下記のようなPHP関数を実行する。

実行結果としては、特定IDのレコードのカラム値がUPDATEされてほしい。

function update($id, $manual_label1, $manual_label2)
{
    var_dump($id, $manual_label1, $manual_label2);

    $pdo = new PDO(DB_DSN);
    $pdo->beginTransaction();

    $sql = "
        update TRAINING set 
                MANUAL_LABEL1 = :manual_label1 
            and MANUAL_LABEL2 = :manual_label2
        where ID = :id
    ";
    $stmt = $pdo->prepare($sql);
    $stmt->execute(
        array(
            ":manual_label1" => $manual_label1,
            ":manual_label2" => $manual_label2,
            ":id" => $id,
        )
    );

    $pdo->commit();
    return;
}

問題

  • 処理は成功する(エラーは出力されない)
  • 意図した値でUPDATEされない。 MANUAL_LABEL1 に 0 が入る。

原因

聡明な方ならお気づきだろうが、SQLが間違っている。

andではなく , でしたと。

typoなんだ許してくれ

 update TRAINING set 
                MANUAL_LABEL1 = :manual_label1 
            and MANUAL_LABEL2 = :manual_label2
        where ID = :id

 update TRAINING set 
                MANUAL_LABEL1 = :manual_label1 
               ,MANUAL_LABEL2 = :manual_label2
        where ID = :id

というよりちゃんとロールバックまでやるべきだが、 どうも例外吐いてすらいなさそう

    try {
        $pdo = new PDO(DB_DSN);
        $pdo->beginTransaction();

        $sql = "
            update TRAINING set 
                    MANUAL_LABEL1 = :manual_label1 
                   ,MANUAL_LABEL2 = :manual_label2
            where ID = :id
        ";
        $stmt = $pdo->prepare($sql);
        $stmt->execute(
            array(
                ":manual_label1" => $manual_label1,
                ":manual_label2" => $manual_label2,
                ":id" => $id,
            )
        );

        $pdo->commit();
    } catch (PDOException $e) {
        $pdo->rollBack();
    }

感想

SQL文法エラーで落ちてくれないですかね・・・