Bra*_*don 5 postgresql postgresql-10
我有一列 type JSONB
,其中每一行都包含一个带有对象数组的 JSON,例如:
[
{
"grade": "4.44/5",
"endYear": 2011,
"startYear": 2006,
"userId": "defg"
},
{
"grade": "9.133/10",
"endYear": 2010,
"startYear": 2006,
"userId": "abcd"
}
]
Run Code Online (Sandbox Code Playgroud)
我正在尝试将这些JSONB
集合扩展为行,例如:
| grade | startYear | endYear | userId |
-------------------------------------------
| 4.44/5 | 2006 | 2011 | defg |
| 9.133/10 | 2006 | 2010 | abcd |
-------------------------------------------
Run Code Online (Sandbox Code Playgroud)
..使用以下查询:
WITH arr AS (SELECT jsonb_array_elements(jsonbrecords) AS jsons
FROM "table-with-jsonb"),
lines AS (
SELECT x.*
FROM arr, jsonb_to_record(jsons) AS x(
"field1" VARCHAR
)
) SELECT *
FROM lines
Run Code Online (Sandbox Code Playgroud)
我正在使用 Datagrip,它对结果进行分页,并且查询对前 500 行完成得很好。
但是,当我尝试加载最后一页结果时,出现此错误:
[22023] ERROR: cannot call populate_composite on a scalar
除了Postgres 源代码之外,谷歌搜索这个错误几乎没有任何有用的结果(对我来说是第一次)。
我不会说 C,但由于jsonb_array_elements
CTE 本身评估得很好,我假设问题是某些行在列中具有标量值jsonbrecords
而不是正确的JSONB
.
为了确保我只有JSONB
值,我删除了不包含'{'
在此查询中的行:
UPDATE "table-with-jsonb" SET jsonbrecords = NULL
WHERE jsonbrecords :: TEXT !~ '{'
Run Code Online (Sandbox Code Playgroud)
这删除了大约十二行,但错误仍然存在。
我还尝试通过检查JSONB
表中的原始行来查找问题,但什么也没找到。
我认为错误意味着一行中没有JSONB
值是否正确?如果是这样,我该如何解决?如果没有,我该如何调试?
无关,但是:您可以将查询简化为:
SELECT x.*
from the_table,
jsonb_array_elements(jsonbrecords) AS t(doc),
jsonb_to_record(t.doc) as x ("grade" text, "userId" text, "endYear" int, "startYear" int);
Run Code Online (Sandbox Code Playgroud)
现在是实际问题。可以通过不jsonb_to_record
单独使用和访问每个键来避免该错误:
SELECT t.doc ->> 'grade' as "grade",
t.doc ->> 'endYear' as "endYear",
t.doc ->> 'startYear' as "startYear",
t.doc ->> 'userId' as "userId"
from the_table,
jsonb_array_elements(jsonbrecords) AS t(doc);
Run Code Online (Sandbox Code Playgroud)
您并没有真正失去灵活性,因为您还需要指定列列表jsonb_to_record()
。
在线示例:http : //rextester.com/VVGJ34083