【问题标题】:Why casting JSONb NULL to a type fails, it is a specification bug?为什么将 JSONb NULL 转换为类型失败,这是一个规范错误?
【发布时间】:2021-12-27 21:27:38
【问题描述】:

作为commented in this answer

SELECT (j->'i')::int FROM  (SELECT '{"i":null}'::jsonb) t(j); -- fail

导致“ERROR: cannot cast jsonb null to type integer”...好吧,这是“PostgreSQL方式”,但是为什么不让它变得更好呢?比添加 CASE 子句更好,它正在做“自然”的事情,即将 JSON-NULL 值转换为 SQL 键入的空值。所以,这不是实现问题,但似乎是 PostregSQL 中的规范错误是吗?

【问题讨论】:

  • Table 8.23. JSON Primitive Types and Corresponding PostgreSQL Types 在文档中确实提到“json null”没有与“SQL NULL 是一个不同的概念”的评论等效的 postgresql 类型,所以我的猜测是这确实是所需的行为.虽然我同意这看起来确实很自然/方便。您可以改用(j->>'i')::int,因为->>'i' 将返回一个text,它可以转换为int(在这种情况下返回null)。
  • stackoverflow.com/q/60163598/2650437 可能也很有趣。
  • 如果您执行 ('[]'::jsonb)::int('{}'::jsonb)::int('"1"'::jsonb)::int 也是一样 - 它们是 JSON 值,无法转换为 int 值。你会得到一个例外,而不是NULL。只有(NULL::jsonb)::int 会变成整数NULL
  • 对于初学者来说,看看这个线程Jsonb strictness。然后在同一列表中搜索json null。底线很多人不想混合 json null 和 SQL NULL。

标签: postgresql casting jsonb


【解决方案1】:

原因是 SQL NULL 与 JSON null 有很大不同。

如果你想这样做:

SELECT nullif((j->'i'), 'null')::int FROM  (SELECT '{"i":null}'::jsonb) t(j);
 nullif 
--------
   NULL
(1 row)

 SELECT pg_typeof(nullif((j->'i'), 'null')::int) FROM  (SELECT '{"i":null}'::jsonb) t(j);
 pg_typeof 
-----------
 integer


SELECT nullif((j->'i'), 'null')::int FROM  (SELECT '{"i": 1}'::jsonb) t(j);
 nullif 
--------
      1
(1 row)

使用 NULLIF 将 JSON null 转换为 SQL NULL

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-10
    相关资源
    最近更新 更多