とあるデータを入手したのだが、それには名称としてカナ名しか設定されていないので、次のような漢字名をDB(SQLite3)に追加するだけの単純なDB更新プログラムを作成してみた。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
<?php /********************************************************************** DB更新処理 ***********************************************************************/ $rkey = "060536"; $kanji = "飯盛山"; try { $pdo = new PDO('sqlite:../data/mountain.sqlite3'); // SQL実行時にもエラーの代わりに例外を投げるように設定 $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); // デフォルトのフェッチモードを連想配列形式に設定 $pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC); $stmt = $pdo->prepare("UPDATE mesh SET nameKanji = :kanji WHERE rkey = :rkey "); $stmt->bindParam(":rkey", $rkey); $stmt->bindParam(":kanji", $kanji); //if ($stmt->execute(array(':kanji' => $kanji, ':rkey' => $rkey))){ if ($stmt->execute()){ print("{$rkey}の更新は正常に終了しました。"); exit(); } else { print_r($sql->errorInfo()); exit(); } $pdo = null; } catch (Exception $e) { echo $e->getMessage() . PHP_EOL; } ?> |
しかし、処理は正常に終了するものの、DBは更新されないのである。
原因不明なまま、悩まされること約1日。
漸くわかった、その原因。
bindParam の指定順番
1 2 |
$stmt->bindParam(":rkey", $rkey); $stmt->bindParam(":kanji", $kanji); |
の部分を
1 2 |
$stmt->bindParam(":kanji", $kanji); $stmt->bindParam(":rkey", $rkey); |
とすることで、更新が正常に行われるようになった。
何とも解せないのは、プレースホルダに “?” を使った次のような場合、
1 2 3 4 5 6 |
$stmt = $pdo->prepare("UPDATE mesh SET nameKanji = ? WHERE rkey = ? "); |
PDO のバグのような気はするのだが。。。私の PHP のバージョンが 7.2 と古いのでその所為かもしれないし、V8.0 以降はそんなバグっぽい現象はとっくに解消しているのかもしれないので、これ以上とやかく言うのはやめ現行の仕様に則り使って行くしかないでしょうな(くっ)。
それにしても無駄な時間を費やしたものだ。とほほ・・・