PostgreSQL unescape JSON字符串

Dan*_*Dan 7 postgresql json

我正在尝试在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.\""]}  
Run Code Online (Sandbox Code Playgroud)

查询:

SELECT json_array_elements(json_column->'comments_array')
Run Code Online (Sandbox Code Playgroud)

返回文档中描述的SET OF JSON.

"Fred said \"Hi.\""
"Fred said \"Hi.\""
"Fred said \"Hi.\""
Run Code Online (Sandbox Code Playgroud)

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

Fred said "Hi."
Fred said "Hi."
Fred said "Hi." 
Run Code Online (Sandbox Code Playgroud)

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

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

Mic*_*ael 6

在其他网站上找到一些简单的内容:\n来源在这里

\n

链接失效时的详细信息:

\n
select (ingredients #>> \'{}\')::jsonb->>\'cheese\' from pizza;\n
Run Code Online (Sandbox Code Playgroud)\n

执行此操作 \xe2\x98\x9d\xef\xb8\x8f。当您\xe2\x80\x99 得到一个带有 jsonb 列(成分)的表(披萨)时,您\xe2\x80\x99 不小心在该列中放入了转义的 JSON 字符串,而不是 JSON 对象。该值可能如下所示:

\n
"{\\"cheese\\": \\"mozzarella\\"}"\n
Run Code Online (Sandbox Code Playgroud)\n

看到引号了吗?\xe2\x80\x99 只是该 JSON 列内根级别的一个字符串。但你真正想要的看起来像这样:

\n
{"cheese": "mozzarella"}\n
Run Code Online (Sandbox Code Playgroud)\n

那\xe2\x80\x99 更好。但我们\xe2\x80\x99已经犯了错误,所以我们\xe2\x80\x99必须编写一个迁移来修复数据。这里\xe2\x80\x99是我们如何做到的:

\n
(ingredients #>> \'{}\')::jsonb\n
Run Code Online (Sandbox Code Playgroud)\n

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

\n

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

\n


小智 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;
Run Code Online (Sandbox Code Playgroud)

然后你可以做这样的事情:

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)
Run Code Online (Sandbox Code Playgroud)

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

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;
Run Code Online (Sandbox Code Playgroud)

然后这样做:

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)
Run Code Online (Sandbox Code Playgroud)