在我们的数据库中,一个 JSONB 列包含一个对象,该对象具有一个属性,该属性是字符串编码的 JSON 对象。我需要在查询期间反序列化该字符串并检查其值。
create table datas (id int, data jsonb);
insert into datas (id, data) values (1, '{"key1": "{\"foo\": \"bar\"}"}');
Run Code Online (Sandbox Code Playgroud)
我可以选择字符串值,但将其转换为 JSONB 对象不起作用。这些查询都返回 null foo
。
select data->'key1'->'foo' from datas;
select to_json(data->'key1')->'foo' from datas;
select (data->'key1')::jsonb->'foo' from datas;
Run Code Online (Sandbox Code Playgroud)
dbfiddle:https://dbfiddle.uk/? rdbms=postgres_9.6&fiddle=9c0a9f7f1323a35051daba5177e52f57
小智 9
text
您需要使用运算符提取值->>
,然后才能将其转换回json
orjsonb
值:
select (data ->> 'key1')::json ->> 'foo'
from datas
Run Code Online (Sandbox Code Playgroud)
但正确的解决方案是不要以每次访问时都需要来回转换的方式存储该值。
这是因为当您将json
(或jsonb
) 转换为text
所有引号时,都会保留。如果您转换'"{\"foo\": \"bar\"}"'
回 JSON,它仍然是单个 JSON 字符串,而不是键/值对。看这里
select (data ->> 'key1')::json ->> 'foo'
from datas
Run Code Online (Sandbox Code Playgroud)
文本 | json | ?柱子? |
---|---|---|
"{\"foo\": \"bar\"}" | "{\"foo\": \"bar\"}" | {“foo”:“酒吧”} |
“某物” | “某物” | 某物 |