gpt4 book ai didi

postgresql - 在 postgres plpgsql 函数中重用 json 解析的输入

转载 作者:行者123 更新时间:2023-11-29 13:50:09 25 4
gpt4 key购买 nike

我有一个 plpgsql 函数,它接受 jsonb 输入,并使用它首先检查某些内容,然后在查询中再次获取结果。像这样的东西:

CREATE OR REPLACE FUNCTION public.my_func(
a jsonb,
OUT inserted integer)
RETURNS integer
LANGUAGE 'plpgsql'
COST 100.0
VOLATILE NOT LEAKPROOF
AS $function$
BEGIN
-- fail if there's something already there
IF EXISTS(
select t.x from jsonb_populate_recordset(null::my_type, a) f inner join some_table t
on f.x = t.x and
f.y = t.y
) THEN
RAISE EXCEPTION 'concurrency violation... already present.';
END IF;

-- straight insert, and collect number of inserted
WITH inserted_rows AS (
INSERT INTO some_table (x, y, z)
SELECT f.x, f.y, f.z
FROM jsonb_populate_recordset(null::my_type, a) f
RETURNING 1
)
SELECT count(*) from inserted_rows INTO inserted
;
END

在这里,我在 IF 检查和实际插入中都使用了 jsonb_populate_recordset(null::my_type, a)。有没有办法进行一次解析——也许是通过某种变量?或者查询优化器会启动并确保解析操作只发生一次吗?

最佳答案

如果我理解正确的话,你会看到这样的东西:

CREATE OR REPLACE FUNCTION public.my_func(
a jsonb,
OUT inserted integer)
RETURNS integer
LANGUAGE 'plpgsql'
COST 100.0
VOLATILE NOT LEAKPROOF
AS $function$
BEGIN
WITH checked_rows AS (
SELECT f.x, f.y, f.z, t.x IS NOT NULL as present
FROM jsonb_populate_recordset(null::my_type, a) f
LEFT join some_table t
on f.x = t.x and f.y = t.y
), vioalted_rows AS (
SELECT count(*) AS violated FROM checked_rows AS c WHERE c.present
), inserted_rows AS (
INSERT INTO some_table (x, y, z)
SELECT c.x, c.y, c.z
FROM checked_rows AS c
WHERE (SELECT violated FROM vioalted_rows) = 0
RETURNING 1
)
SELECT count(*) from inserted_rows INTO inserted
;

IF inserted = 0 THEN
RAISE EXCEPTION 'concurrency violation... already present.';
END IF;

END;
$function$;

关于postgresql - 在 postgres plpgsql 函数中重用 json 解析的输入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42554223/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com