【问题标题】:Strange JSON interpretation (polymorphic type), how to workaround?奇怪的JSON解释(多态类型),如何解决?
【发布时间】:2017-12-30 03:27:49
【问题描述】:

这个合法的(!)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 hum... 我同意 JSON“数据类型”(你有 "official link" 断言我们必须将其作为数据类型忽略吗?),但也许我们可以将 JSONb 视为真实的数据类型...必须是“一等公民”才能有意义并与 MongoDB 等 noSQL 竞争。
  • 在文档示例中,演员表在文本上:SELECT CASE WHEN true THEN to_json(1) ELSE to_json('hello'::text) END;
  • @peterkrauss 你可能是对的;在您的用例中,json 是一种数据类型,这不是您的技术问题的原因。我没有足够的知识来解决这个问题,这就是我发表评论但没有给出答案的原因。即使您的问题是“合法时间(!)”,但对我来说,有条件输入的输出是一种代码味道,可能意味着周围业务逻辑的结构有问题。 [stackoverflow.com/questions/24257726/…link) 是否相关?
  • @JGH 你的例子有效吗?什么postgresql版本?

标签: json postgresql casting polymorphism


【解决方案1】:

反过来做:

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

将“你好”声明为类型text。 这样您就可以将1 保留为数字,将'hello' 保留为字符串。
显式转换 'hello'::text 是等价的。

原因是 Postgres 类型系统。未加引号的 1 是合法的数字常量,默认为 Postgres 数据类型 integer。但是'hello' 只是一个以unknown 类型开头的字符串文字。函数to_json()是多态的,也就是说它的输入参数定义为ANYELEMENT。它的实际作用取决于输入数据类型。它不知道如何处理数据类型unknown。因此出现错误消息。

无论哪种情况,结果数据类型都是json(这是常规 Postgres 数据类型),但这与问题正交。

相关:

【讨论】:

    猜你喜欢
    • 2013-10-21
    • 1970-01-01
    • 2012-01-09
    • 2011-06-13
    • 2020-07-24
    • 1970-01-01
    • 2018-05-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多