如何从 PL/lpgSQL 函数内部获取记录(行)的 jsonb 数组的键和值
How to get keys and values of jsonb array for a record (row) from inside PL/lpgSQL function
我在 table 中有一个文本列,其中包含 city/country 类型的数据,可转换为 jsonb,例如:
SELECT
'{"Toronto":"Canada","Moscow":"Russia","New York":"USA"}'::text
AS city_data
我必须将其转换为 JSONB
这种格式的数组:
[
{
"city": "Moscow",
"match": false,
"country": "Russia"
},
{
"city": "Toronto",
"match": false,
"country": "Canada"
},
{
"city": "New York",
"match": false,
"country": "USA"
}
]
我可以在常规 PostgreSQL 查询中做到这一点,首先获取每个 key/value,然后将其聚合回 JSONB 数组。
WITH data AS (
WITH city_table AS (
SELECT
'{"Toronto":"Canada","Moscow":"Russia","New York":"USA"}'::text AS city_data
)
SELECT cities.key AS city, cities.value AS country
FROM city_table
LEFT JOIN jsonb_each_text(city_data::jsonb) cities ON true
)
SELECT jsonb_agg(jsonb_build_object(
'city', city::text,
'country', country::text,
'match', false::boolean)) AS combined
FROM data
但我不知道如何在 PL/pgSQL 函数中执行此 LEFT JOIN。
函数在游标上循环,在满足某个条件的地方,我需要做这个转换并存储到一个变量中。
即在光标 cur
内,对于记录 rec
,我必须得到相应的 rec.city_data
,将其转换为新格式,并将其保存到变量 var_city_data
如何在 rec
上执行 LEFT JOIN?通常在记录中我只调用 rec.field_name
而不需要做任何 FROM
...
我试过了:
FOR rec IN cur LOOP
-- conditions........
WITH data AS (
SELECT cities.key AS city, cities.value AS country
FROM rec -- I THINK THE ERROR IS SOMEWHERE HERE AND NEXT LINE
LEFT JOIN jsonb_each_text(rec.city_data::jsonb) cities ON true
)
SELECT INTO var_city_data
jsonb_agg(jsonb_build_object('city', city::text,
'country', country::text,
'match', false::boolean))
FROM data;
RAISE NOTICE 'city_data: % ', var_city_data;
-- ... other conditions...
END LOOP;
我也尝试删除 FROM rec
,直接执行 FROM jsonb_each_text(rec.city_data::jsonb)
等,但我不断收到 PL/pgSQL function inline_code_block
.
类型的错误
如有任何帮助,我们将不胜感激。
注意:此函数必须在 PostgreSQL 9.6 和 11+ 版本上运行
不需要LEFT JOIN
或WITH
条款。
只需尝试以下查询:
FOR rec IN cur LOOP
-- conditions........
SELECT jsonb_agg(jsonb_build_object(
'city', cities.key::text,
'country', cities.value::text,
'match', false::boolean))
INTO var_city_data
FROM jsonb_each_text(rec.city_data::jsonb) cities(key,value);
RAISE NOTICE 'city_data: % ', var_city_data;
-- ... other conditions...
END LOOP;
我在 table 中有一个文本列,其中包含 city/country 类型的数据,可转换为 jsonb,例如:
SELECT
'{"Toronto":"Canada","Moscow":"Russia","New York":"USA"}'::text
AS city_data
我必须将其转换为 JSONB
这种格式的数组:
[
{
"city": "Moscow",
"match": false,
"country": "Russia"
},
{
"city": "Toronto",
"match": false,
"country": "Canada"
},
{
"city": "New York",
"match": false,
"country": "USA"
}
]
我可以在常规 PostgreSQL 查询中做到这一点,首先获取每个 key/value,然后将其聚合回 JSONB 数组。
WITH data AS (
WITH city_table AS (
SELECT
'{"Toronto":"Canada","Moscow":"Russia","New York":"USA"}'::text AS city_data
)
SELECT cities.key AS city, cities.value AS country
FROM city_table
LEFT JOIN jsonb_each_text(city_data::jsonb) cities ON true
)
SELECT jsonb_agg(jsonb_build_object(
'city', city::text,
'country', country::text,
'match', false::boolean)) AS combined
FROM data
但我不知道如何在 PL/pgSQL 函数中执行此 LEFT JOIN。
函数在游标上循环,在满足某个条件的地方,我需要做这个转换并存储到一个变量中。
即在光标 cur
内,对于记录 rec
,我必须得到相应的 rec.city_data
,将其转换为新格式,并将其保存到变量 var_city_data
如何在 rec
上执行 LEFT JOIN?通常在记录中我只调用 rec.field_name
而不需要做任何 FROM
...
我试过了:
FOR rec IN cur LOOP
-- conditions........
WITH data AS (
SELECT cities.key AS city, cities.value AS country
FROM rec -- I THINK THE ERROR IS SOMEWHERE HERE AND NEXT LINE
LEFT JOIN jsonb_each_text(rec.city_data::jsonb) cities ON true
)
SELECT INTO var_city_data
jsonb_agg(jsonb_build_object('city', city::text,
'country', country::text,
'match', false::boolean))
FROM data;
RAISE NOTICE 'city_data: % ', var_city_data;
-- ... other conditions...
END LOOP;
我也尝试删除 FROM rec
,直接执行 FROM jsonb_each_text(rec.city_data::jsonb)
等,但我不断收到 PL/pgSQL function inline_code_block
.
如有任何帮助,我们将不胜感激。
注意:此函数必须在 PostgreSQL 9.6 和 11+ 版本上运行
不需要LEFT JOIN
或WITH
条款。
只需尝试以下查询:
FOR rec IN cur LOOP
-- conditions........
SELECT jsonb_agg(jsonb_build_object(
'city', cities.key::text,
'country', cities.value::text,
'match', false::boolean))
INTO var_city_data
FROM jsonb_each_text(rec.city_data::jsonb) cities(key,value);
RAISE NOTICE 'city_data: % ', var_city_data;
-- ... other conditions...
END LOOP;