twitter facebook

PostgreSQLでの JSONの深いキーの更新など

postgresql で JSON/JSONB を扱うことができますが、以下のようなJSON を更新するときの課題です。
{"test": {"test2":{ "test3": "hoge"}}}

JSON_SET や JSON_SET_LAX を使用した場合

JSON_SET や JSON_SET_LAX は既存のJSONデータを破壊せずに更新できるクエリーです。JSONB_SET_LAX のみ説明すると
text_json->'test'->'test2'->'test3' というキーのJSON を 'hoge' という値にしたい場合
UPDATE t_test
SET test_json = JSONB_SET_LAX(
 test_json ::jsonb,
 '{test, test2, test3}', 
 '"hoge"'::jsonb, 
 TRUE, 
'use_jsonb_null' 
) WHERE test_id='3087'
JSONが以下の状態であれば追加・更新できますが
{"test": {"test2":{ "test3": "test"}}}
{"test": {"test2":{}}}

JSONが以下の状態だと追加・更新されません。何も起きないという感じになります。

{"test": {}}
{}
つまり 'test2' のキーが存在してない場合は test3 は更新・追加されません。
*第4引数が true の場合はキーがつくられるとおもいきや 最後のキー(test3)の1つ前のキー(test2)は存在している必要があるようです。
で、力技で、第1引数 を以下のようにして・・・・
COALESCE(test_json, '{}'::jsonb) || '{"test": {"test2": {}}}'::jsonb,..."
・・・でいけるはいけます・・・
UPDATE t_test
SET test_json = JSONB_SET_LAX(
 COALESCE(test_json, '{}'::jsonb) || '{"test": {"test2": {}}}'::jsonb,
  '{test, test2, test3}', 
  '"hoge"'::jsonb, 
 TRUE,  'use_jsonb_null' 
)
WHERE test_id='3087'

連想配列っぽく

そこでLLMにきいてもいい案がでなく、ぐぐっていたら見つけました。
直観的に全て解決できそうなクエリーです。
UPDATE t_test
SET  test_json['test']['test2']['test3']= '"Wine"'
WHERE test_id='3087'
以下のように プログラムの連想配列に値を設定するかのように設定すると キーのあるなし関係なく設定が可能です!
SET test_json['test']['test2']['test3']= '"Wine"'
うれしいことに test_json が NULL であっても ちゃんと値が設定されました
AMAZON アソシエイト
AUTHOR
@えのえの
最終更新日 2025/11/06
FAVORITE good stock
LINK TAG
記法を見る