PostgreSQL でのことである。
あるテーブルの JSONB型に、以下のようなJSON値があるとする。
{ "a":{ "a1": "Apple", "a2": "Lemon" } }
このJSONの"a1" を null にする場合、シングルクォートで括った
文字列 ' null' 指定した以下なら成功する。
UPDATE jbooks SET jdata = jsonb_set(jdata, '{a,a1}', 'null') WHERE id = 4
しかし、null をシングルクォートで括らずに
jdata = jsonb_set(jdata, '{a,a1}', null)
としてしまうと、JSONB型のデータ列に null が入ってしまいパスで
指定した値だけを null にできない。
PostgreSQL バージョン13から、jsonb_set_lax と関数が拡張されており、
jsonb_set(target jsonb, path text, new_value jsonb[, create_missing boolean])
の create_missing boolean を省略せずに
jsonb_set_lax( target jsonb, path text, new_value jsonb
[, create_if_missing boolean [, null_value_treatment text ]] )
null_value_treatment を指定することで new_value が null の時の振る舞いを指定する。
null_value_treatment は、
raise_exception | new_value が null ならエラーになり、22004:NULL VALUE NOT ALLOWED になる |
use_json_null | new_value が null なら null がセットされる |
delete_key | path で設定された JSONはキーと値が削除される |
return_target | new_value が null なら変更されない、null でなければそのまま反映される。 |
だから、
jdata = jsonb_set_lax(jdata, '{a,a1}', null, true, 'use_json_null')
とすれば、期待どおり
{ "a":{ "a1": null, "a2": "Lemon" } }
になる。
oboe2uran.hatenablog.com
ここで書いたmybatis の mapper は、jsonb_set _lax を使わずに jsonb_set のままでも
null のセットを対応している。
PosetgreSQLのバージョン13 以上の限定になることはないであろう。