はじめに
こんにちは。ブログと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を触ろうとしている人はちょっと注意してください。
それでは。