Vous pouvez trouver un index d'un élément recherché en utilisant jsonb_array_elements() with ordinality
(note, ordinality
commence à 1 alors que le premier index du tableau json est 0) :
select
pos- 1 as elem_index
from
samples,
jsonb_array_elements(sample->'result') with ordinality arr(elem, pos)
where
id = 26 and
elem->>'8410' = 'FERR_R';
elem_index
------------
2
(1 row)
Utilisez la requête ci-dessus pour mettre à jour l'élément en fonction de son index (notez que le deuxième argument de jsonb_set()
est un tableau de texte) :
update
samples
set
sample =
jsonb_set(
sample,
array['result', elem_index::text, 'ratingtext'],
'"some individual text"'::jsonb,
true)
from (
select
pos- 1 as elem_index
from
samples,
jsonb_array_elements(sample->'result') with ordinality arr(elem, pos)
where
id = 26 and
elem->>'8410' = 'FERR_R'
) sub
where
id = 26;
Résultat :
select id, jsonb_pretty(sample)
from samples;
id | jsonb_pretty
----+--------------------------------------------------
26 | { +
| "result": [ +
| { +
| "8410": "ABNDAT", +
| "8411": "Abnahmedatum" +
| }, +
| { +
| "8410": "ABNZIT", +
| "8411": "Abnahmezeit" +
| }, +
| { +
| "8410": "FERR_R", +
| "8411": "Ferritin", +
| "ratingtext": "Some individual text"+
| } +
| ] +
| }
(1 row)
Le dernier argument dans jsonb_set()
doit être true
pour forcer l'ajout d'une nouvelle valeur si sa clé n'existe pas encore. Il peut cependant être ignoré car sa valeur par défaut est true
.
Bien que les problèmes de concurrence semblent peu probables (en raison de la condition WHERE restrictive et d'un nombre potentiellement faible de lignes affectées), vous pouvez également être intéressé par Atomic UPDATE .. SELECT dans Postgres.