xyz
という名前のJSONB列が[Postgres 9.6]にあるとします。更新では、この列の.foo.bar
キーを{"done":true}
に設定します。
ただし、更新では、xyz
の更新前の値が{}
から
{
"abc": "Hello"
}
または多分
{
"foo": {
"baz": { "done": false }
},
"abc": "Hello"
}
jsonb_set
が定義されていないと失敗するため、すぐにxyz->foo
を使用することはできません。その場合、jsonb_insert
を使用できますが、xyz->foo
isが既に定義されている場合は失敗します。
だから私はのようなもので連結を使用しようとします
jsonb_set(
jsonb_set(xyz, '{foo}', '{}'::jsonb || xyz->'foo', true),
'{foo, bar}', '{"done":true}', true
)
...xyz->'foo'
はfoo
であるため、null
が未定義の場合も失敗します。これは、連結で{}
をオーバーライドします。
明らかに、これを回避するためにif
を使用する関数を作成することもできますが、1回の更新で実行できるはずです。
この例では:
{
"foo": {
"baz": { "done": false }
},
"abc": "Hello"
}
挿入:
jsonb_insert
を使用する必要があります。SELECT
でテストできます。
SELECT jsonb_insert(xyz, '{foo,bar}', '{"done":true}'::jsonb) FROM tablename;
注:パスを正しく設定するには、jsonb_insert
を使用することが非常に重要です。ここでのパスは '{foo:bar}'です。つまり、foo
というオブジェクトbar
内にJSONを挿入します。
したがって、結果は次のとおりです。
{
"abc": "Hello",
"foo": {
"baz": {
"done": false
},
"bar": {
"done": true
}
}
}
セット:
bar
を編集してfalseに設定するには、jsonb_set
を使用する必要があります。 SELECT
でテストできます:
SELECT jsonb_set(xyz, '{foo,bar}', '{"done":false}'::jsonb) FROM tablename;
これは次を返します:
{
"abc": "Hello",
"foo": {
"baz": {
"done": false
},
"bar": {
"done": false
}
}
}
SETおよびINSERTの更新
オブジェクトが存在する場合はjsonb_set
を使用し、存在しない場合はjsonb_insert
を使用します。どちらを使用するかを知らずに更新するには、CASE
を使用できます
UPDATE tablename SET
xyz= (CASE
WHEN xyz->'foo' IS NOT NULL
THEN jsonb_set(xyz, '{foo,bar}', '{"done":false}'::jsonb)
WHEN xyz->'foo' IS NULL
THEN jsonb_insert(xyz, '{foo}', '{"bar":{"done":true}}'::jsonb)
END)
WHERE id=1;-- if you use an id to identify the JSON.
より具体的な値に対して、いくつかのCASE句を追加できます。
使用できます||連結する。 json値を上書きまたは追加します。
SELECT '{}'::jsonb || '{"foo":"bar"}'::jsonb
UPDATE tablename SET jdoc = jdoc || '{"foo":"bar"}'::jsonb
とても簡単です。ソフトウェアで関数を使用することはほとんどありません。