7

我正在尝试使用 PostgreSQL 9.3 中的新 JSON 功能,并且我正在寻找一个使 JSON 转义的函数,它与 to_json(anyelement) 相反。

下面是一个示例 JSON:

{"single_comment": "Fred said \"Hi.\"" , 
"comments_array": ["Fred said \"Hi.\"", "Fred said \"Hi.\"", "Fred said \"Hi.\""]}  

查询:

SELECT json_array_elements(json_column->'comments_array')

如文档中所述返回 SET OF JSON。

"Fred said \"Hi.\""
"Fred said \"Hi.\""
"Fred said \"Hi.\""

有没有办法取消结果,所以我可以得到以下结果:

Fred said "Hi."
Fred said "Hi."
Fred said "Hi." 

在文档中,我没有看到任何可以帮助我的功能。不幸的是,安装 PLV8 对我来说不是一个选择。

任何想法都受到高度赞赏。

4

4 回答 4

2

我自己也遇到过这个问题,这就是我的处理方法。我创建了一个辅助函数,它遍历数组并使用 ->> 运算符使用下标来获取文本值。如果有人知道更好的方法,我很高兴听到,因为这似乎有点笨拙。

CREATE OR REPLACE FUNCTION json_text_array_to_pg_text_array(data json) returns text[] AS $$
DECLARE
    i integer;
    agg text[];
BEGIN
    FOR i IN 0..json_array_length(data)-1 LOOP
        agg := array_append(agg, data->>i);
    END LOOP;

    return agg;
END
$$ language plpgsql;

然后您可以执行以下操作:

test=# select json_text_array_to_pg_text_array('[ "hello","the\"re","i''m", "an", "array" ]'::json);
 json_text_array_to_pg_text_array 
----------------------------------
 {hello,"the\"re",i'm,an,array}
(1 row)

如果您不想直接处理数组,也可以使函数只返回一组文本:

CREATE OR REPLACE FUNCTION json_text_array_to_row(data json) returns setof text AS $$
DECLARE
    i integer;
BEGIN
    FOR i IN 0..json_array_length(data)-1 LOOP
        return next data->>i;
    END LOOP;
    return;
END
$$ language plpgsql;

然后这样做:

test=# select json_text_array_to_row('{"single_comment": "Fred said \"Hi.\"" ,"comments_array": ["Fred said \"Hi.\"", "Fred said \"Hi.\"", "Fred said \"Hi.\""]}'::json->'comments_array');
 json_text_array_to_row 
------------------------
 Fred said "Hi."
 Fred said "Hi."
 Fred said "Hi."
(3 rows)
于 2014-05-26T00:45:15.173 回答
2
select t.comments->>0 from 
(select jsonb_array_elements(your_table.json_column->'comments_array') as comments
from your_table) as t;
于 2016-01-24T13:49:12.177 回答
1

在其他网站上找到一些简单的东西:来源这里

链接失效时的详细信息:

select (ingredients #>> '{}')::jsonb->>'cheese' from pizza;

这样做☝️。当您有一个带有 jsonb 列(成分)的表(披萨)时,您不小心在该列中放置了一个转义的 JSON 字符串,而不是 JSON 对象。该值可能如下所示:

"{\"cheese\": \"mozzarella\"}"

看到报价了吗?这只是该 JSON 列内根级别的字符串。但你真正想要的是这样的:

{"cheese": "mozzarella"}

这样更好。但是我们已经犯了错误,所以我们必须编写一个迁移来修复数据。我们是这样做的:

(ingredients #>> '{}')::jsonb

Postgres 中的#>>运算符获取“指定路径处的 JSON 对象作为文本”(PostgreSQL:文档:9.3:JSON 函数和运算符)。这里我们传入一个空路径,表示我们希望 Postgres 将根级别的未转义字符串作为text值提供给我们。

然后我们可以text像这样将该值转换回 JSON (stand-in-for-text-value)::jsonb:然后我们在根级别有一个普通的、已解析的 JSON 对象,我们可以从中选择字段。

于 2022-01-27T12:24:48.927 回答
0

我已经设法通过对 JSON 的少量修改来实现结果:

{"comments_array": [{"comment": "Fred said \"Hi.\""}, {"comment": "Fred said \"Hello.\""}]}

现在我们使用对象数组而不是字符串数组,并且以下查询可以按我的意愿工作:

SELECT (json_array_elements(json_column->'comments_array'))->>'comment'

现在这将满足我的需求,但如果有人知道我们如何实现字符串数组的输出,请分享它:)

于 2013-10-18T07:37:11.550 回答