我觉得我必须在这里错过一些简单的东西,但我已经查看了PostgreSQL关于JSON和JSON运算符和函数的文档,并且看不到任何解释它的内容。
在PostgreSQL中将事物变成JSON很容易:
SELECT *, pg_typeof(j) FROM (VALUES
(to_json(5)),
(to_json(true)),
(to_json('foo'::TEXT))
) x (j);
会给我一个很好的结果集json
s:
j | pg_typeof
-------+-----------
5 | json
true | json
"foo" | json
但是,如何将这些json
值转换回到原始类型?当然,我不希望能够在一个结果集中完成所有操作,因为类型不一致。我只是个人意思。
强制转换不起作用:
SELECT to_json(5)::NUMERIC;
给出
ERROR: cannot cast type json to numeric
如果我尝试滥用json_populate_record
功能,请执行以下操作:
SELECT json_populate_record(null::INTEGER, to_json(5));
我得到了
ERROR: first argument of json_populate_record must be a row type
在PG 9.4中,我可以很容易地告诉类型:SELECT json_typeof(to_json(5));
给出了number
,但这并没有帮助我实际提取它。
json_to_record
(也是9.4):
SELECT * FROM json_to_record(to_json(5)) x (i INT);
给我另一个错误:
ERROR: cannot call json_to_record on a scalar
那么如何将json
“标量”(显然是PG调用它们)转换为相应的PG类型?
我对9.3和9.4感兴趣; 9.2只是奖金。
答案 0 :(得分:9)
布尔值和数字的最简单方法似乎是首先转换为TEXT
然后转换为适当的类型:
SELECT j::TEXT::NUMERIC
FROM (VALUES ('5.4575e6'::json)) x (j)
-- Result is 5457500, with column type NUMERIC
SELECT j::TEXT::BOOLEAN
FROM (VALUES ('true'::json)) x (j)
-- Result is t, with column type BOOLEAN
这会留下字符串,您可以在此处获取引用的值:
SELECT j::TEXT
FROM (VALUES (to_json('foo'::TEXT))) x (j)
-- Result is "foo"
显然,我的问题的这一部分has already been addressed。您可以通过将文本值包装在数组中然后将其解压缩来解决它:
SELECT array_to_json(array[j])->>0
FROM (VALUES (to_json('foo'::TEXT))) x (j)
-- Result is foo, with column type TEXT.
答案 1 :(得分:4)
第一步:如果您的值包含在结构中(通常是这种情况),则需要使用正确的运算符/函数来提取数据的字符串表示形式:->>
(9.3 +),{{1 }(9.3+),#>>
(9.3 +),json_each_text()
(9.4 +)。
要在9.3中选择json数组元素的文本表示,你需要这样的东西:
json_array_elements_text()
对于标量值,您可以使用这个小技巧:
select json_array ->> indx
from generate_series(0, json_array_length(json_array) - 1) indx
此时,处理字符串和 nulls (通过这些方法将sson select ('[' || json_scalar || ']')::json ->> 0 -- ...
限制为json null)。要选择数字,您需要使用强制转换为NULL
(完全 1 与json的数字兼容)。要选择布尔,请使用强制转换为numeric
(支持boolean
和true
作为输入表示。但请注意,如果不接受其输入表示,则强制转换会使查询失败。 F.ex.如果你的某些列中有一个json对象,那么该对象通常有一些键,通常是 号(但不总是),这个查询可能会失败:
false
如果您有此类数据,则需要使用select (json_object ->> 'key')::numeric
from your_table
(9.4 +)过滤您的选择:
json_typeof()
1 我没有检查他们的完整语法,但select (json_object ->> 'key')::numeric
from your_table
where json_typeof(json_object -> 'key') = 'number'
也接受科学记数法,所以从理论上讲,所有json数字都应该正确处理。
对于9.2+,此函数可以测试json值的类型:
numeric
答案 2 :(得分:1)
This is question similar to yours.本质上,数据类型的基础位级表示是不兼容的,并且由于涉及的含糊不清,将标量转换为本机类型并不是已实现的。 JSON有一个非常严格的规范,与javascript对象和本机密切对应。
有可能,但我认为它尚未实施。