普段思ったことや、雑記。

Menu & Search

PostgreSQLに文字列を保存する際にはシングルクォートのエスケープに注意する

2016年9月29日

PostgreSQLのクエリに対し、文字列と定義した変数を事前にシングルクォートで囲っていても、変数の文字列内にシングルクォートがあり、エスケープしていなければクエリのエラー要因に

MySQLの場合は文字列を表現する場合には、シングルクォートまたはダブルクォートのどちらかで対象文字列を囲う。PostgreSQLでは、これが厳密にシングルクォートとまず決まっている(ダブルクォートで囲ってもエラーになる)。例えば、Node.jsとbrianc/node-postgres(pg)をで下記のようなクエリのコードを書いただけではエラーになってしまう。

let [name,email] = ['mmiyauchi','[email protected]'];
let profile = `こんにちは!私はJavaScriptがわりと好きです!('-')b`;

const query = `INSERT INTO member (name, email, profile) VALUES ('${name}', '${email}', '${profile}')`;

時期的に、そろそろES6でも良いかなと思っているので、このブログで紹介するコードも基本的にはES6のシンタックスで取り扱うこととする。もし、読みにくい場合はBabel公式のこちらのトランスパイラでES5コードに変換して確認して欲しい。ということで、問題はコードのハイライト箇所の2行目である。シングルクォートなんて、ソースコード以外、あまりテキストに出てこないということだろう。そういうわけで、クローリングだったり、未知のテキストをPostgreSQLに放り込むというという時に顔文字なんかが当たって、エラーを引き起こすことがある(まさに実際に顔文字でこの事態になり、シングルクォートがテキストデータ内にあり、悪さをしていたことにようやく気付いた)。

 

PostgreSQLのテキスト内のシングルクォートのエスケープの仕方にはウェブを探すといくつかの方法があるようだ。その中でもSQL標準である「シングルクォートが1つあれば、シングルクォート2つに置換」のエスケープの仕方が推奨

PostgreSQLの推進団体Let’s Postgres公式サイトのこちらのページによると、テキスト中のシングルクォートのエスケープについては下記のように説明されている。

SQL標準で定義されているエスケープ方法は、単純に1つのシングルクォートを2つに重ねることです

前述のように、通常はシングルクォートが1つあれば、シングルクォートを2つに置換してエスケープする方法が推奨されている。というわけで、実際のJavaScriptコードで、エスケープ処理を加えたコード例を下記に示す。

//シングルクォートが1つあればシングルクォートを2つ(double)に置換する関数
const doubleSingleQuote = (text) => {
  const regex = /\'/;
  let fixedText = '';
  if (regex.test(text)) {
    text = text.toString();
    fixedText = text.replace(/\'/g, '\'\'');
    return fixedText;
  } else {
    return text;
  }
};

let [name,email] = ['mmiyauchi','[email protected]'];
let profile = `こんにちは!私はJavaScriptがわりと好きです!('')b`;

//文字列を格納する変数に全てついてシングルクォートのエスケープ処理をする
name = doubleSingleQuote(name);
email = doubleSingleQuote(email);
profile = doubleSingleQuote(profile);

const query = `INSERT INTO member (name, email, profile) VALUES ('${name}', '${email}', '${profile}')`;

上記シングルクォートのエスケープ処理については、簡単な正規表現で低コストで実装できる。おそらく大体似たような処理になると思うが、参考までに共有であった。

Article Tags
mmiyauchi

プログラムを書きながらTranceを聴くのが良いですね。みなさんも聴いたほうがいいですよ、Trance。EDMよりハードトランスでしょ。

Related article

Redux(react-redux)における適切な配列要素の更新

2021年8月23日…

CloudFlareの『SSL/TLS 暗号化モード(HTTPS通信設定)』を使用したとき、『ERR SSL VERSION OR CIPHER MISMATCH』のエラーでChromeで発生し、接続できない場合の対処

英語の記事は見当たっ…

Dart(Flutter)についての所見

Dart(Flutter)についての所見

第一印象では、クロス…

Discussion about this post

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください

Type your search keyword, and press enter to search