简体   繁体   中英

Postgres how to iterate over nested JSON object

I have an object as below. I would like to iterate over each user in insert and insert them into my database. I'm stuck at how to reach the inner objects. I have a code like below and I'm stuck on how to go further into the obejct, it only gets insert , delete and update . I am using postgresql for this.

I see ->> int Get JSON array element as text '[1,2,3]'::json->>2 in the docs but not sure how to incorporate into my code

DECLARE
   _key   text;
   _value text;
BEGIN
    FOR _key, _value IN
       SELECT * FROM jsonb_each_text($1)
    LOOP
       RAISE NOTICE '%: %', _key, _value;
    END LOOP;

    RETURN input;
END




 {
      insert: {
        jsmith:
        { 
          name: 'John Smith',
          mail: 'JSmith@smith.com',
          jobTitle: 'Lead',
          hasImage: true,
          teamId: '35' 
        },
        lmark:
        {
          name: 'Laurendy Mark',
          mail: 'LMark@mark.com',
          jobTitle: 'System Admin',
          hasImage: true,
          teamId: '40'
        }
      },
      delete: {
        lbeth
        {
          name: 'Lisa Beth',
          mail: 'LBeth@smith.com',
          jobTitle: 'Assistant Director',
          hasImage: true,
          teamId: '40',
          uid: '200'
        }
      },
      update: {}
    }

You don't really need a PL/pgSQL function for this. This can be done using a data modifying CTE

with input (col) as (
  values ('
    {
       "insert":{ 
        "jsmith":{"name":"John Smith", "mail":"JSmith@smith.com","jobTitle":"Lead","hasImage":true,"teamId":35},
        "lmark":{"name":"Laurendy Mark","mail":"LMark@mark.com","jobTitle":"System Admin","hasImage":true,"teamId":40}
       },
       "delete":{
         "lbeth":{"name":"Lisa Beth","mail":"LBeth@smith.com","jobTitle":"Assistant Director","hasImage":true,"teamId":40,"uid":200}
       },
       "update":{}
    }'::jsonb)
), do_insert as (
  insert into the_table (name, mail, job_title, has_image, team_id)
  select i.value ->> 'name', 
         i.value ->> 'mail',
         i.value ->> 'jobTitle',
         (i.value ->> 'hasImage')::boolean,
         (i.value ->> 'teamId')::int
  from input
   cross join jsonb_each(col -> 'insert') i
  returning *
), do_delete as (
  delete from the_table
  where uid in (select (i.value ->> 'uid')::int
                 from input
                   cross join jsonb_each(col -> 'delete') i)
)                   
update the_table
  set has_image = (i.value ->> 'hasImage')::boolean
from input
 cross join jsonb_each(col -> 'update') i
where (i.value ->> 'uid')::int = the_table.uid
;

Online example

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM