Postgres - 将数据从嵌套 json 插入 table

Postgres - Insert data into table from nested json

我正在尝试将嵌套的 json 数据插入到 table(用户)中,如果 table 中尚不存在该记录。我将 json 数据从 API 传递给 Postgres 函数 fn_update_users_test。数据代表我的应用程序的新用户,并包含我要插入到用户 table 中的数据(如果记录尚不存在)。在 insert 语句中,我尝试使用 json_populate_recordset 但我没有找到任何有效的方法。帮忙,你在我的圣诞名单上! :)

从 API-

传入的 p_userlist 参数(JSON 数据)的值
 [{"kind":"admin#directory#user","id":"107135403825787437500","etag":"\"mZ6zy6fy8dMbMO7K4FrHYhYwAYXvzlQcofJtEqj2VHI/q1RDqamBEi9qC6fodTrbYDOka8g\"","primaryEmail":"John@acme.com","name":{"givenName":"John","familyName":"Doe","fullName":"John Doe"},"emails":[{"address":"John@acme.com","primary":true},{"address":"John@acme.com.test-google-a.com"}]}

我要插入的table是-

 CREATE TABLE public.users
(
userid bigint NOT NULL GENERATED ALWAYS AS IDENTITY ( INCREMENT 1 START 1 MINVALUE 1 MAXVALUE 
9223372036854775807 CACHE 1 ),
firstname character varying COLLATE pg_catalog."default" NOT NULL,
lastname character varying COLLATE pg_catalog."default" NOT NULL,
email character varying COLLATE pg_catalog."default" NOT NULL,
phone character varying COLLATE pg_catalog."default",
isemailenabled boolean DEFAULT false,
ptorate integer
)

函数是-

 CREATE OR REPLACE FUNCTION public.fn_update_users_test(
p_userlist json)
RETURNS integer
LANGUAGE 'plpgsql'

COST 100
VOLATILE 
AS $BODY$
BEGIN

with customer_json (doc) as (
  values 
 (p_userlist::json)
)
insert into public."users" (firstname, lastname, email, phone, isemailenabled, ptorate)
select l."name"->givenName, l."name"->familyName, l.primaryEmail, l.phone, FALSE, 0
from customer_json l
cross join lateral json_populate_recordset(null::public."users", doc) as p
where l."primaryEmail" not in (SELECT email FROM public."users");
      
RETURN 1;  

结束; $BODY$;

如何修复函数以便它解析数据然后将数据插入用户 table?谢谢!

终于想通了。我的错误在于语法。使用“->”是访问 json 的嵌套元素的正确方法,提取值应该是“->>”。我还有一些其他问题,但简而言之,以下 sql 完美运行-

 CREATE OR REPLACE FUNCTION public.fn_update_users_test(
p_userlist json)
RETURNS integer
LANGUAGE 'plpgsql'

COST 100
VOLATILE 
 AS $BODY$
 BEGIN
drop table  IF EXISTS userlist;
drop table  IF EXISTS newusers;
CREATE TEMPORARY TABLE userlist (
firstname text,
lastname text,
email text,
phonearray text,
isemailenabled boolean,
ptorate integer default 0
);
CREATE TEMPORARY TABLE newusers (
firstname text,
lastname text,
email text,
phone text,
isemailenabled boolean,
ptorate integer default 0
);
insert into userlist (firstname, lastname, email, phonearray, isemailenabled, ptorate)
SELECT (sub.element->'name'->>'givenName')::character varying as firstname, 
(sub.element->'name'->>'familyName') as lastname,
(sub.element->>'primaryEmail') as email, (sub.element->'phones'->0->>'value') as 
phone, false, 0
FROM 
 (SELECT json_array_elements(p_userlist) as element) as sub;
--insert new users
INSERT INTO public."users" (firstname, lastname, email, phone, isemailenabled, 
ptorate)
select firstname::character varying, lastname::character varying, email::character 
varying, phonearray, isemailenabled, ptorate
from userlist ul where ul.email not in (select email from public."users");

RETURN 1; -
drop table userlist;
drop table newusers;

END;
$BODY$;