You don't need any loops for this.
The SELECT for the first INSERT is wrong, because the value you are passing isn't an array. You only need to access the properties directly from the passed parameter. As this is a single row, no looping is required to begin with.
To insert the roles, you also don't need a loop, just use jsonb_array_elements()
as the source for the INSERT statement:
create function save_user(p_user_data jsonb)
returns int
as
$$
declare
v_id int;
begin
insert into users (firstname, lastname, email)
select p_user_data ->> 'firstName',
p_user_data ->> 'lastName',
p_user_data ->> 'email'
returning id
into v_id;
insert into userroles (userid, roleid)
select v_id, (r.item ->> 'id')::int
from jsonb_array_elements(p_user_data -> 'roles') as r(item);
return v_id;
end;
$$
language plpgsql;
I used jsonb
rather than json
here, because that's the recommended data type when JSON is involved.
Online example
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…