はじめに
こんにちは。ブログとQiitaの使い分けがいまいちできない鮎月(あゆつき)です。
Qiitaの投稿は2つ目になりますが、タイトル通りの話です。
一応確認ですが、このモジュールについてのお話です:
2つのエスケープ方法
Node.jsのMySQLモジュールには、2つのエスケープ処理の方法があります。
connection.escape()
例としてこんな感じになります (公式Docより)
var userId = 'some user provided value';
var sql = 'SELECT * FROM users WHERE id = ' + connection.escape(userId);
connection.query(sql, function (error, results, fields) {
if (error) throw error;
// ...
});
ちなみに公式Docには次のような説明も。
In order to avoid SQL Injection attacks, you should always escape any user provided data before using it inside a SQL query. You can do so using the mysql.escape(), connection.escape() or pool.escape() methods:
意訳) SQLインジェクション回避したいなら connection.escape()
とか使ってな
疑問符プレースホルダー
普通はこっち?
またまた公式Docのサンプルコードです
connection.query('SELECT * FROM users WHERE id = ?', [userId], function (error, results, fields) {
if (error) throw error;
// ...
});
またまた公式Docより引用:
Alternatively, you can use ? characters as placeholders for values you would like to have escaped like this:
意訳) 「?」をプレースホルダーとして使えるで
This looks similar to prepared statements in MySQL, however it really just uses the same
connection.escape()
method internally.
DeepL訳) これは MySQL のプリペアドステートメントに似ていますが、実際には内部で同じ connection.escape()
メソッドを使用しているだけです。
この一文のせいです。
こいつのせいで当時(今でも)MySQL初心者の私はドツボにハマりました。
今までに使っていたエスケープ処理
最初は、connection.escape()
を用いたエスケープをしていました。
公式Docにもこれが最初に書かれてたし、疑問符プレースホルダーはあまり使われないのかなーなんて思ってました。(DB触るの初めてだったから)
しかし、これを使うと文字列が面白い形で格納されます。
というのも、文字列が'
で囲まれます。
公式Docによると
Strings are safely escaped
訳) 文字列は安全にエスケープされます
だそうです。
公式Docには、先ほどの「実際には内部で同じ connection.escape()
メソッドを使用しているだけです」とあったので、正直こういう仕様なのかと思ってました。
疑問符プレースホルダーでもこうなるのかと。
そんなことはなかった
先日ふとした思いつきで、疑問符プレースホルダーを試してみました。
なぜ初めて触る時に試さなかったのかは聞かないでください。
するとどうでしょう。
なんの記号で囲まれることもなく、素直に格納されました。
発狂した。
つまり
内部的には connection.escape()
と同じとか書いてありましたが、実際は若干違います。
面白いことを起こしたくないなら何が何でも疑問符プレースホルダーを使いましょう。
って1年前の私に言いたい。
そんな話なので、Node.jsでMySQLを触ろうとしている人はちょっと注意してください。
それでは。