2017-04-19 7 views
1

私はPostgresの9.5を使用していると私はタイプ「JSON」の欄(「情報」)を持っている...私はこの挿入をやろうとしている:PostgreSQLを使用して、json列の ""をエスケープするにはどうすればよいですか?

INSERT INTO table (info) 
VALUES (
    '{"entry":"((\+)[0-9]+)"}' 
) 

が、私はこのエラーを取得:

ERROR: invalid input syntax for type json 
DETAIL: Escape sequence "\+" is invalid. 

これはエスケープシーケンスとして\+を解釈していますが、私は実際にそれを自分の価値の一部として欲しがります。一般的に

+0

これが所属する場所を取得し、[dba.se]に移行するフラグを設定してください。 –

答えて

2

  • あなたがキーと値を持っている場合は、文字列からキャストするリテラルJSONオブジェクトを書いているならば、それは適切でなければならないオブジェクト
  • を構築するためにjsonb_build_objectを使用します。適切なJSON文字列にはエスケープする必要があります\

説明

PostgreSQLはこれを引用されていません:それはRFC 7159次だけのJSON implimentationです。

A string begins and ends with quotation marks. All Unicode characters may be placed within the quotation marks, except for the characters that must be escaped: quotation mark, reverse solidus, and the control characters (U+0000 through U+001F). [... ] So, for example, a string containing only a single reverse solidus character may be represented more compactly as "\\" .

これはリテラル形式のようです。 \+はJSONで有効な文字列ではありませんので、だから、この意志ない仕事を

CREATE TABLE tbl 
AS 
    SELECT '{"entry":"((\\+)[0-9]+)"}'::jsonb AS info; 

ドル引用符のPostgreSQLには無エスケープを必要としませんが、それはここでは助けにはなりません、

Notice that inside the dollar-quoted string, single quotes can be used without needing to be escaped. Indeed, no characters inside a dollar-quoted string are ever escaped: the string content is always written literally. Backslashes are not special, and neither are dollar signs, unless they are part of a sequence matching the opening tag.

。しかし、私たちがjsonタイプを使用していない場合にはうまくいくでしょう。

SELECT '{"key":"\"}'::jsonb; 
ERROR: invalid input syntax for type json 
LINE 1: SELECT '{"key":"\"}'::jsonb; 
      ^
DETAIL: Token ""\"}" is invalid. 
CONTEXT: JSON data, line 1: {"key":"\"} 

ただし、

SELECT FORMAT($${%s:%s}$$, to_jsonb(k), to_jsonb(v))::jsonb 
FROM (VALUES 
    ('key', '\') 
) AS t(k,v); 

.. JSON-エスケープ文字列にto_jsonb()を使用することができます。しかし、あなたはキーと値を持っている場合はjson_build_object

を使用できるためにも、これは悪い考えです
SELECT jsonb_build_object(k, v) 
FROM (VALUES 
    ('key', '\') 
) AS t(k,v); 
+0

これは動作しますが、データベースの列ではエスケープされますが、このエントリ(つまり((\\ +)[0-9] +)データ。エスケープされていない元の値を返す方法はありますか? – user3228515

関連する問題