[SQLite] クォーテーションを含むテキストを書き込むときは、プリペアドステートメントを使うべし

先日とあるシステムでハードにSQL書き込みを行う作業をしていた時のこと。 なんかエラーがでて、データベースが書き込みできていない状態を見つけてしまった。 そのエラーの原因が、書き込むテキストの中にクォーテーション文字列が含まれていることが原因だったので、エスケープすれば解決できると安易に考えていたけど、意外とエラーが直らなかったので、最終的にプリペアステートメントという記述で事なきを得たという備忘録をブログに残しておきます。

エラーについて

SQLiteに対して、次のようなINSERTを行った時にエラーが出ました $id = 1 $value = '"sample"'; $sqlite = new \SQLite3("data.sqlite") $query = <<<__QUERY__ INSERT INTO TextHeader ( id, value ) VALUES ( "{$id}", "{$value}" ) __QUERY__; $sqlite->connect(); $res = $sqlite->query($sql); $sqlite->close(); 【Error】 Error : sqlite query Unable to prepare statement

プリペアドステートメントを使う

$id = 1 $value = '"sample"'; $sqlite = new \SQLite3("data.sqlite") $query = <<<__QUERY__ INSERT INTO TextHeader ( id, value ) VALUES ( :id, :value ) __QUERY__; $sqlite->connect(); $prepare = $sqlite->prepare($sql); $prepare->bindValue(':id' , $id); $prepare->bindValue(':value' , $value); $res = $prepare->execute(); $sqlite->close();

ちょっと解説

色違いの箇所が変更点です。 まず、普通にqueryやexecしていたところを、prepareのステートメントを実行します。 prepareを実行したインスタンスに、bindValue()という設定で、prepareで指定したkeyと変数をバインドしてあげます。(わかりやすいように変数名にしてますが、同じじゃなくても動作します) 最後に、execute()して処理実行をすると、通常通りSQL書き込みが可能になります。 このプリペアドステートメントは、SELECTなどにも使えるので、お試しあれ。