#json #postgresql #loops #plpgsql #jsonb
#json #postgresql #циклы #plpgsql #jsonb
Вопрос:
Я пытаюсь создать функцию plpg, принимающую в качестве параметра :
[{'id_product': 100000158, 'd_price': '7,75'}, {'id_product': 100000339, 'd_price': '9,76'}]
Или, может быть :
{'products': [{'id_product': 100000158, 'd_price': '7,75'}, {'id_product': 100000339, 'd_price': '9,76'}]}
Пока не могу определить наилучший подход.
Я хочу преобразовать этот объект или строку jsonb в массив, чтобы я мог выполнять цикл по нему. Идея состоит в том, чтобы выполнять цикл en каждый {'id_product': xxxxxxxxx, 'd_price': 'xxxxx'}
раз, поэтому я, если значения в таблице одинаковы.
Каков наиболее оптимальный способ сделать это? Я все еще играю с функциями jsonb.
Ответ №1:
Вы можете создать функцию, содержащую JSONB_POPULATE_RECORDSET()
function
CREATE OR REPLACE FUNCTION fn_extract_elements( i_jsonb JSONB )
RETURNS TABLE (o_product VARCHAR(500), o_price VARCHAR(500))
AS $BODY$
BEGIN
RETURN QUERY
WITH tab AS
(
SELECT *
FROM JSONB_POPULATE_RECORDSET(NULL::record,i_jsonb )
AS tab(id_product VARCHAR(500), d_price VARCHAR(500))
)
SELECT *
FROM tab;
END
$BODY$
LANGUAGE plpgsql;
и вызывайте таким образом, чтобы
SELECT *
FROM fn_extract_elements(
'[{"id_product": "100000158", "d_price": "7,75"},
{"id_product": "100000339", "d_price": "9,76"}]'
);
o_product o_price
100000158 7,75
100000339 9,76
Ответ №2:
Вот решение для тех, кто, возможно, захочет сделать что-то подобное :
Я изменил ввод на что-то вроде : {0: [100000158, 7.76], 1: [100000339, 9.76]}
И функция :
CREATE OR REPLACE FUNCTION public.check_d_price(
p_products jsonb)
RETURNS jsonb
LANGUAGE 'plpgsql'
COST 100
VOLATILE PARALLEL UNSAFE
AS $BODY$
DECLARE
_key varchar;
_real_price NUMERIC;
_bad_price jsonb;
BEGIN
FOR _key IN (
SELECT jsonb_object_keys(p_products)
)
LOOP
SELECT ei.price INTO _real_price FROM product pr JOIN ecom_input ei ON (pr.ecom_id,pr.sku) = (ei.ecom_id,ei.sku_supplier) WHERE pr.id = (p_products->_key->>0)::INT;
IF _real_price <> (p_products->_key->>1)::NUMERIC THEN
_bad_price = COALESCE(_bad_price,'{}'::jsonb) || jsonb_build_object((p_products->_key->>0)::TEXT,
jsonb_build_object('d_price', p_products->_key->>1,'new_price', _real_price));
END IF;
END LOOP;
RETURN _bad_price;
END;
$BODY$;