PostgreSQL
 sql >> Base de données >  >> RDS >> PostgreSQL

Utilisation de jsonb_set() pour mettre à jour une valeur de tableau jsonb spécifique

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.