総括
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文法エラーで落ちてくれないですかね・・・