Postgresql

為什麼 JSON 元素在不是文本時返回文本?

  • July 6, 2017

當我嘗試訪問 JSON 元素時,->>'elementName'我得到了一個text類型。

SELECT pg_typeof(x1->>'a'), jsonb_typeof(x2)
FROM ( VALUES
 ('{"a":5}'::jsonb, '5'::jsonb)
) AS t(x1,x2);

pg_typeof | jsonb_typeof 
-----------+--------------
text      | number
(1 row)

但是,jsonb說它將數字映射到數字類型……

在將文本 JSON 輸入轉換為 jsonb 時,RFC 7159 描述的原始類型有效地映射到原生 PostgreSQL 類型,如表 8-23 所示。

這是從文件中複製的表格,

表 8-23。JSON 基本類型和對應的 PostgreSQL 類型

JSON primitive type     PostgreSQL type  Notes
string                  text             \u0000 is disallowed, as are non-ASCII Unicode escapes if database encoding is not UTF8
number                  numeric          NaN and infinity values are disallowed
boolean                 boolean          Only lowercase true and false spellings are accepted
null                    (none)           SQL NULL is a different concept

目前無法訪問內部 JSON 類型。上面引用的文件只提到了它們的儲存方式。PostgreSQL 中有一個偽類型anyelement,但你不能返回那個類型。函式是多態的,因為它們接受不同的類型,但它們必須返回指定的類型。

運算符可以針對不同的類型進行重載,但目前還不是這樣。目前->>定義為

Operator    Right Operand Type  Description
->>         text                Get JSON object field as text

這意味著無論類型如何儲存,都必須通過text才能訪問它。所有jsonb運算符都返回jsonbor text

即使類型被重載,也要考慮歧義,如何處理。

SELECT pg_typeof(x1->>'a'), jsonb_typeof(x2)
FROM ( VALUES
 ('{"a":5}'::jsonb, '5'),
 ('{"a":true}'::jsonb, 'true'::jsonb)
) AS t(x1,x2);

如果這是有道理的..那麼這是做什麼的..

SELECT sum(x1->>'a')
FROM ( VALUES
 ('{"a":5}'::jsonb, '5'),
 ('{"a":true}'::jsonb, 'true'::jsonb)
) AS t(x1,x2);

雖然重載->>可能會使系統更高效,但也會使其複雜得多。

引用自:https://dba.stackexchange.com/questions/168029