奇怪的JSON解析(多态类型),如何解决?

3
这个合法的(!) CASE 结构返回一个 JSON 数据类型:
 SELECT CASE WHEN true THEN to_json(1) ELSE to_json('hello') END;

但是:

错误:无法确定多态类型,因为输入具有“未知”类型

它不是“多态的”,它是JSON格式的。

... 因此,作为糟糕的解决方法(丢失数字/字符串的JSON表示),

 SELECT to_json(CASE WHEN true THEN 1::text ELSE 'hello' END);

有没有更好的方法将SQL转换为JSON?


JSON不是一种数据类型。JSON是一种用于指定任意类型数据的对象表示法。1是一个数字,"hello"是一个字符串。您无法指定一个既可以是数字又可以是字符串的值。您的解决方法之所以有效是因为1::text或"1"是一个字符串,现在您始终在构建字符串数据类型。如果您想有时使用数字,有时使用字符串,可以将其包装在较大的对象中。例如,{id: 1, word: ""}可以是一个输出,{id: null, word: "hello"}可以是另一个输出,并且您可以基于布尔值构建这些输出。 - anandsun
1
就像文档示例中所示,将转换应用于文本:SELECT CASE WHEN true THEN to_json(1) ELSE to_json('hello'::text) END; - JGH
@JGH,你的示例代码能正常运行吗?使用的是哪个版本的PostgreSQL? - Peter Krauss
另一种不太优美的解决方案:SELECT CASE WHEN true THEN json_build_object('result',1) ELSE json_build_object('result','hello') END - Peter Krauss
@PeterKrauss 是的,在9.6.1版本下。请参见演示 - JGH
显示剩余3条评论
1个回答

6

反过来做:

SELECT CASE WHEN true THEN to_json(1) ELSE to_json(<b>text 'hello'</b>) END;

声明'hello'为类型text。 这样你保留1作为数字和'hello'作为字符串。
显式转换'hello'::text是等效的。
原因是Postgres类型系统。未引用的1是一个合法的数值常量,并默认为Postgres数据类型integer。但是带有单引号的'hello'是一个以unknown类型开始的字符串字面量。函数to_json()是多态的,其输入参数被定义为ANYELEMENT。输出取决于输入数据类型。它不知道如何处理unknown数据类型。因此出现错误消息。
结果数据类型在任何情况下都是json(这是一个常规的Postgres数据类型),但这与问题无关。
相关:

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接