Postgresql 在plpgsql中识别jsonb null的最佳实践

Postgresql 在plpgsql中识别jsonb null的最佳实践,postgresql,plpgsql,Postgresql,Plpgsql,我知道以前有人问过这个问题: 也许其他人。。。 我无法从上面的链接中收集到的是是否有最佳实践 考虑以下代码: DO $$ DECLARE _main_jsonb jsonb = '{"i_am_null": null, "a_string": "null"}'; _sub_jsonb jsonb; BEGIN SELECT (_main_jsonb->'i_am_null') INTO _sub_jsonb; IF

我知道以前有人问过这个问题:

也许其他人。。。 我无法从上面的链接中收集到的是是否有最佳实践

考虑以下代码:

DO
$$
DECLARE
  _main_jsonb jsonb = '{"i_am_null": null, "a_string": "null"}';
  _sub_jsonb jsonb;
BEGIN
  SELECT (_main_jsonb->'i_am_null') INTO _sub_jsonb;
  IF _sub_jsonb IS NULL THEN
    RAISE INFO 'This point *not* reached. Bad?';
  END IF;

  -- THIS IS THE PART I AM REALLY INTERESTED IN
  SELECT (_main_jsonb->>'i_am_null')::jsonb INTO _sub_jsonb;
  IF _sub_jsonb IS NULL THEN
    RAISE INFO 'This point *is* reached. Good.';
  END IF;
  -- THIS IS THE PART I AM REALLY INTERESTED IN

  SELECT (_main_jsonb->>'a_string')::jsonb INTO _sub_jsonb;
  IF _sub_jsonb IS NULL THEN
    RAISE INFO 'Bonus points. This point *not* reached. Good.';
  END IF;
END;
$$
有没有更好的方法来判断i_am_null是否为null


编辑:仅供对这个问题感兴趣的人参考,

您的两个链接答案都包含解决方案,但最好有一个综合答案

Postgres是强类型的。它的函数和运算符返回特定类型

->返回jsonb

->>返回文本和文本

请注意,虽然jsonb null只是另一个值,但SQL null非常特殊。Null不是一个值,它是缺少一个值。将null强制转换为jsonb可能会产生jsonbnull,但是SQL标准要求null只强制转换为null,否则这意味着null等同于某些东西

这就是为什么jsonb null可以转换为null,但null不能转换为jsonb null。null::jsonb为null。这很不方便,但SQL标准要求这样做。这是不建议在jsonb和text之间来回转换的原因之一。

有jsonb_类型的函数:

json\u类型的json→ 正文

jsonb_类型jsonb→ 正文

以文本字符串形式返回顶级JSON值的类型。可能的类型有object、array、string、number、boolean和null。null结果不应与SQL null相混淆;参见示例

json_-typeof'-123.4'→ 数

json_'null'的类型:json→ 空的

json_typeofNULL::json为空→ t

所以如果jsonb_类型的某些值='null',那么。。。正如我所理解的,这就是你想要的


请注意,现有的键i_am_null返回文本“null”,缺少的键foo返回SQL null。

真null是什么意思?我链接的问题的两个变体之一确实讨论了null的字符串值,因此我将null与null区分开来。坦白地说,我的代码无论如何都不会传递null。不过,我刚刚编辑了我的最后一个问题,如果这有帮助,=NULL将永远不会匹配。我想您正在寻找='null'::jsonb。这将与sql NULL不匹配,但是,正如_main_jsonb->“i_do_not_exist”返回的那样,不确定那里需要什么。@Bergi thx the=NULL确实是一个万岁。我把它放在那里是因为这个问题的一个变体的答案提到JSON null和SQL null略有不同-所以我发疯了,认为这是不可能的。。。但是我现在把注意力从我的问题中移开了。“贝基,谢谢,我正困惑于为什么选择‘NULL’::JSONB::文本是空的;这是错误的。我想->>有它自己的逻辑。当我消化这一点时,我发现自己仍然困惑不解_main_jsonb->“i_am_null”是jsonb。_main_jsonb->>“i_am_null”也是:jsonb。正当但其中只有一个可以成功地与SQL NULL进行比较。如果我说得通的话,我希望这个答案能涵盖这一点。@Wellspring它不是内部表示,而是返回类型。Postgres是强类型的。->返回jsonb,因此得到jsonb null。->>返回文本以便获取文本,文本可以为空。null等于零,null不能转换为包含jsonb null的任何值,因此null::jsonb为null。@Wellspring->>的问题在于它以不同的方式将不同的json类型转换为文本。也许有帮助。第一行中的注释说明了为什么将字符串字段强制转换回jsonb是个坏主意。那么您是否同意IF _sub_jsonb='null'::jsonb和IF jsonb_typeofsome_jsonb_value='null'是函数等价物?如果是的话,这是Tomato/Tomato的事情还是有最佳实践建议?如果不是的话,我想最快的方法就是最好的方法。
test=# select '{"i_am_null": null, "a_string": "null"}'::jsonb->'i_am_null' = 'null'::jsonb;
 ?column? 
----------
 t
(1 row)

test=# select '{"i_am_null": null, "a_string": "null"}'::jsonb->'a_string' = 'null'::jsonb;
 ?column? 
----------
 f
(1 row)
test=# select '{"i_am_null": null, "a_string": "null"}'::jsonb->>'i_am_null' is null;
 ?column? 
----------
 t
(1 row)

test=# select '{"i_am_null": null, "a_string": "null"}'::jsonb->>'a_string' is null;
 ?column? 
----------
 f
(1 row)
with t(x) as (values('{"i_am_null": null, "a_string": "null"}'::jsonb))
select
    *,
    jsonb_typeof(x->'i_am_null') as "i_am_null",
    jsonb_typeof(x->'a_string') as "a_string",
    jsonb_typeof(x->'foo') as "foo"
from t;

┌─────────────────────────────────────────┬───────────┬──────────┬──────┐
│                    x                    │ i_am_null │ a_string │ foo  │
├─────────────────────────────────────────┼───────────┼──────────┼──────┤
│ {"a_string": "null", "i_am_null": null} │ null      │ string   │ ░░░░ │
└─────────────────────────────────────────┴───────────┴──────────┴──────┘