我希望它可以array_to_json
与array_agg
. 有关用法,请参阅PostgreSQL 9.2 json 文档,以及支持在 PostgreSQL 9.1 中使用的 JSON 功能直到 9.2 发布的json91模块,或使用 9.2 beta。
不幸的是,事实证明,此时似乎没有任何对合并、聚合等 json 的支持。这使得构建 JSON 值变得异常困难。我只是用常规的文本运算符来做这件事,但这不允许引用问题。
regress=# SELECT '{'||string_agg('"'||attr||'": "'||val||'"', ', ')||'}' FROM t1;
?column?
-----------------------------------------------------
{"attr1": "val1", "attr2": "val3", "attr3": "val3"}
(1 row)
看:
regress=# insert into t1 (attr,val) values ('at"tr', 'v"a"l');
INSERT 0 1
regress=# SELECT '{'||string_agg('"'||attr||'": "'||val||'"', ', ')||'}' FROM t1;
?column?
-----------------------------------------------------------------------
{"attr1": "val1", "attr2": "val3", "attr3": "val3", "at"tr": "v"a"l"}
(1 row)
regress=# SELECT ('{'||string_agg('"'||attr||'": "'||val||'"', ', ')||'}')::json FROM t1;
ERROR: invalid input syntax for type json
DETAIL: line 1: Token "tr" is invalid.
您添加到答案中的解决方案中存在相同的问题。为了得到一个好的答案,我们需要类似 的函数json_escape_literal
,目前还没有类似的函数暴露给 SQL。
我在 Pg 的当前 json 功能集上看到的唯一安全方法是生成一个对数组,但这并不比使用普通的面向行的查询更好。
regress=# SELECT array_to_json( array_agg( array_to_json( ARRAY[attr, val] ) )) FROM t1;
array_to_json
---------------------------------------------------------------------------
[["attr1","val1"],["attr2","val3"],["attr3","val3"],["at\"tr","v\"a\"l"]]
您可能可以结合使用 hstore 和 json 来做您想做的事,但这就是扩展汤。这真正需要的是一个等效于的 json 对象构造函数,hstore(text[],text[])
因此您可以执行以下 json 等效项:
select hstore( array_agg(attr), array_agg(val) ) from t1;
更新:关于此主题的 pgsql-general 邮件列表帖子