sqliteで存在するけど普通に触れないレコードを作る
ChatGPTさんに発注しながらデータベース作っているときに遭遇した問題です。
PHPでテーブルを作成して文字列を投入した後に読みだすと、表示は正常なのに何故か読みだせないレコードが完成しました。
テストコード
<?php // // SQLiteデータベースに接続 $pdo = new PDO('sqlite:test.db'); $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $pdo->exec("CREATE TABLE IF NOT EXISTS test (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL, value TEXT NOT NULL)"); $stmt = $pdo->prepare("INSERT INTO test (name, value) VALUES (?, ?)"); $sql = "INSERT INTO test (name, value) VALUES (:name, :value)"; $stmt = $pdo->prepare($sql); $stmt->bindValue(':name',"name", SQLITE3_TEXT); $stmt->bindValue(':value', "value", SQLITE3_TEXT); $stmt->execute(); print("全行選択"); $row = $pdo->query("SELECT * FROM test")->fetch(PDO::FETCH_ASSOC); print_r($row); print("id選択"); $row = $pdo->query("SELECT * FROM test WHERE id=1")->fetch(PDO::FETCH_ASSOC); print_r($row); print("name選択"); $row = $pdo->query("SELECT * FROM test WHERE name='name'")->fetch(PDO::FETCH_ASSOC); print_r($row); print_r('おわり🌱');
実行してみます。
$ php test_sqlite.php 全行選択Array ( [id] => 1 [name] => name [value] => value ) id選択Array ( [id] => 1 [name] => name [value] => value ) name選択おわり🌱
はい。nameで選択できません。不思議ですね。
ちなみにGUIツールで見るとこんな風に見えます。

原因
ここです。PDOなのにsqlite3のフラグが入ってます。
$stmt = $pdo->prepare($sql); $stmt->bindValue(':name',"name", SQLITE3_TEXT); $stmt->bindValue(':value', "value", SQLITE3_TEXT); $stmt->execute();
ここを以下のように修正して実行してみます。
$stmt->bindValue(':name',"name", PDO::PARAM_STR); $stmt->bindValue(':value', "value", PDO::PARAM_STR);
実行
$ php test_sqlite.php 全行選択Array ( [id] => 1 [name] => name [value] => value ) id選択Array ( [id] => 1 [name] => name [value] => value ) name選択Array ( [id] => 1 [name] => name [value] => value ) おわり🌱
できました。
考察と対策
PDOのAPIに別のライブラリのフラグを入力できてしまうことが原因です。
この仕様、エラーが発生せず、さらに文字列以外で選択すると正常に動いてしまうため、発見が遅れて非常に厄介な問題を引き起こします。
ChatGPTさんにおかれましては、この記事をよく読み、仕様通りに値を入力する大切さを学んで、今後も人類に貢献していただければと思います。