postgresql 使用JSON字符串格式参数在Redshift中创建临时表

k7fdbhmy  于 2023-11-18  发布在  PostgreSQL
关注(0)|答案(1)|浏览(178)

我有一个红移存储的proc签名,看起来像

CREATE OR REPLACE PROCEDURE get_filtered_results
(
    p_id smallint,
    p_filters varchar(65535), 
    rs_out REFCURSOR
)
LANGUAGE plpgsql

字符串
p_filters是JSON格式的字符串。

[{idToFilter: 1, range:'2:2', idChildren: 4, description: 'blabla1'}, {idToFilter: 2, range:'3:5', idChildren: 3, description: 'blabla2'},
{idToFilter: 3, range:'2:6', idChildren: 2, description: 'blabla3'}]


我希望能够将该字符串转换为一个临时表,其中每个属性都是一列,数组的每条记录都是表中的一行,查询类似于

CREATE TEMPORARY TABLE tmp_filter
    AS
    (
        SELECT * FROM JSON_PARSE(p_filters)
    );


有没有简单的方法?

djmepvbi

djmepvbi1#

就像我之前说的,让我们把它分成几块。

#1将字符串转换为行和列

这里的第一个问题是你的字符串不是有效的JSON。JSON需要双引号而不是单引号,但这很容易解决。然而,字符串仍然是无效的,因为标识符也需要引号。所以当你有:
[{idToFilter:1,范围:“2:2”,idChildren:4、产品描述:“blabla1'},{idToFilter:2,range:'3:5',idChildren:3,description:'blabla2'},{idToFilter:3,range:'2:6',idChildren:2,description:'blabla3'}]
它真的需要:
[{“idToFilter”:1,“range”:“2:2”,“idChildren”:4,“description”:“blabla1”},{“idToFilter”:2,“range”:“3:5”,“idChildren”:3,“description”:“blabla2”},{“idToFilter”:3,“range”:“2:6”,“idChildren”:2,“description”:“blabla3”}]
您需要修改输入字符串(至少是标识符的引号)才能使其正常工作。
然后我们需要将字符串转换为super,然后展开它。这样的SQL看起来像:

create table test as select '[{\'idToFilter\': 1, \'range\':\'2:2\', \'idChildren\': 4, \'description\': \'blabla1\'}, {\'idToFilter\': 2, \'range\':\'3:5\', \'idChildren\': 3, \'description\': \'blabla2\'},
{\'idToFilter\': 3, \'range\':\'2:6\', \'idChildren\': 2, \'description\': \'blabla3\'}]' as p_filters; 

SET enable_case_sensitive_identifier TO true;

with fix_quotes as (
select replace(p_filters,'\'','"') as p_filters from test
),
json_value as (
SELECT JSON_PARSE(p_filters) as json from fix_quotes
)
select i."idToFilter", i.range, i."idChildren", i.description 
from json_value j, j.json i;

字符串
本例中的第一个CTE是将引号更改为双引号。(我手动更改了初始字符串以修复缺少的引号。)第二个CTE将值转换为SUPER。顶部选择展开super。
还要注意,你需要在Redshift会话中更改为区分大小写的标识符,因为你的JSON中有大写字符。
从这里开始,剩下的步骤就是编码了,但让我们先看看这是否有意义。这确实是问题的核心。其他步骤将把这个查询 Package 在一个CTAS中,并将其全部放入一个存储的proc中,并传递输入字符串。这些步骤很简单,但如果需要更多,我可以提供帮助。

相关问题