2016-08-10 102 views
11

私はjsonb列のDBテーブルを持っています。postgres jsonb_set複数のキーの更新

number | data 
    1 | {"name": "firstName", "city": "toronto", "province": "ON"} 

データ列を更新する方法が必要です。 だから私の出力は次のようになります。

{"name": "firstName", "city": "ottawa", "province": "ON", "phone": "phonenum", "prefix": "prefixedName"} 

はjson_setと、それは可能ですか?私のようなクエリ追加した :

update table_name set data = jsonb_set(data, '{city}', '"ottawa"') where number = 1; 

はしかし、私はそれが存在しない場合は、新しいキーと値を追加し、それが存在する場合は、キー値を更新する方法が必要です。単一のクエリでこれを達成することは可能ですか?

答えて

18

documentation says

||演算子は、各オペランドの最上位レベルで要素を連結します。 ...たとえば、両方のオペランドが共通のキーフィールド名を持つオブジェクトである場合、結果のフィールドの値は右手オペランドの値になります。

だからあなたの例のデータを使用して:

update table_name set 
    data = data || '{"city": "ottawa", "phone": "phonenum", "prefix": "prefixedName"}' 
where number = 1; 

さらに編集したいオブジェクトがトップレベルでない場合 - ちょうど連結とjsonb_set機能を兼ね備えています。元のデータが

... 
data = jsonb_set(data, '{location}', data->'location' || '{"city": "ottawa", "phone": "phonenum", "prefix": "prefixedName"}') 
... 
+0

これは魅力的です。ありがとう!私は十分なポイントを持っていないので、まだそれをアップアップすることはできませんが、確かに親指をアップ。 – phpfreak

+0

postgresのドキュメントを完全に失うことなくどのように読んだのですか –

+1

@MarcoPrins Oracleのドキュメントを読もうとしましたか?これと比較すると、PostgreSQLのドキュメントは文学の傑作です:o) – Abelisto

1

その後、

{"location": {"name": "firstName", "city": "toronto", "province": "ON"}} 

のように見える場合たとえば、あなたはここでは2つのjsonbオブジェクト

update table_name set data = (select val from (
(select 
CASE WHEN data ? key THEN jsonb_set(data, '{' || key || '}', quote_nullable(updated_value)) 
ELSE 
data || ('{' || quote_ident(key) || ':' || quote_ident(some_value) || '}')::jsonb 
END val 
from json_each_text((select data::json from tbl)) 
CROSS JOIN tbl t 
where key in ('city','phone','prefix') and number=1)) where number=1 
を連結する jsonb concatation演算子 ||を使用しているこの

を試すことができます

+1

[jsonb in postgres](https://www.postgresql.org/docs/9.6/static/functions-json.html)を参照してください。 – Paarth

関連する問題