- 类别:
:doc:`/sql-reference/functions-semistructured`(解析)
PARSE_JSON¶
将输入字符串解释为 JSON 文档,并生成一个 VARIANT 值。
- 另请参阅:
语法¶
PARSE_JSON( <expr> )
实参¶
expr
保存有效 JSON 信息的字符串类型的表达式(例如 VARCHAR)。
返回¶
返回值为 VARIANT
类型,包含 JSON 文档。
此函数不返回 结构化类型。
使用说明¶
此函数支持最大压缩大小为 8 MB 的输入表达式。
如果使用空字符串或仅包含空格字符的字符串调用 PARSE_JSON 函数,则该函数返回 NULL(而不是抛出错误),即使空字符串不是有效的 JSON。这允许处理继续,而不是在某些输入为空字符串时中止。
如果输入为 NULL,则输出也是 NULL。但是,如果输入字符串为
'null'
,那么它将被解释为 JSON null 值,因此结果不是 SQL NULL,而是包含null
的有效 VARIANT。下面的示例部分包含一个示例。解析十进制数时,PARSE_JSON 试图通过将 123.45 视为 NUMBER(5,2) 而不是 DOUBLE 来保持表示的准确性。但是,使用科学记数法(例如 1.2345e+02)的数字或由于范围或比例限制而无法存储为定点小数的数字存储为 DOUBLE。因为 JSON 本身不表示 TIMESTAMP、DATE、TIME 或 BINARY 等值,所以这些值必须表示为字符串。
在 JSON 中,对象(也称为“字典”或“哈希”)是一组 无序 的键值对。
TO_JSON
和 ``PARSE_JSON``(几乎)是相反或互逆的函数。PARSE_JSON
函数接受一个字符串作为输入,并返回一个 JSON 兼容的 VARIANT。TO_JSON
函数接受一个 JSON 兼容的 VARIANT 并返回一个字符串。
如果 X 是包含有效 JSON 的字符串,则以下内容(从概念上讲)为真:
X = TO_JSON(PARSE_JSON(X));
例如,以下情况(从概念上讲)为真:
'{"pi":3.14,"e":2.71}' = TO_JSON(PARSE_JSON('{"pi":3.14,"e":2.71}'))
但是,这些函数并不完全互逆,因为:
空字符串和只有空格的字符串不会互逆。例如,
PARSE_JSON('')
的返回值为 NULL,但TO_JSON(NULL)
的返回值不是''
。TO_JSON
生成的字符串中键值对的顺序是不可预测的。TO_JSON
生成的字符串可以比传递给PARSE_JSON
的字符串具有更少的空格。
例如,以下是等效的 JSON,但不是等效的字符串:
{"pi": 3.14, "e": 2.71}
{"e":2.71,"pi":3.14}
示例¶
这显示了一个通过调用 PARSE_JSON
解析字符串在 VARIANT 列中存储不同类型数据的示例。
创建并填写表。请注意,
INSERT
语句使用PARSE_JSON
函数。CREATE OR REPLACE TABLE vartab (n NUMBER(2), v VARIANT); INSERT INTO vartab SELECT column1 AS n, PARSE_JSON(column2) AS v FROM VALUES (1, 'null'), (2, null), (3, 'true'), (4, '-17'), (5, '123.12'), (6, '1.912e2'), (7, '"Om ara pa ca na dhih" '), (8, '[-1, 12, 289, 2188, false,]'), (9, '{ "x" : "abc", "y" : false, "z": 10} ') AS vals;查询数据:
SELECT n, v, TYPEOF(v) FROM vartab ORDER BY n;
以下示例显示了 PARSE_JSON
和 TO_JSON
的 NULL 处理:
SELECT TO_JSON(NULL), TO_JSON('null'::VARIANT), PARSE_JSON(NULL), PARSE_JSON('null'); +---------------+--------------------------+------------------+--------------------+ | TO_JSON(NULL) | TO_JSON('NULL'::VARIANT) | PARSE_JSON(NULL) | PARSE_JSON('NULL') | |---------------+--------------------------+------------------+--------------------| | NULL | "null" | NULL | null | +---------------+--------------------------+------------------+--------------------+
以下示例演示了 PARSE_JSON
、TO_JSON
和 TO_VARIANT
之间的关系:
创建一个表并添加 VARCHAR、泛型 VARIANT 和 JSON 兼容 VARIANT 数据。INSERT 语句插入一个 VARCHAR 值,UPDATE 语句生成一个对应于该 VARCHAR 的 JSON 值。
CREATE or replace TABLE jdemo2 (varchar1 VARCHAR, variant1 VARIANT, variant2 VARIANT); INSERT INTO jdemo2 (varchar1) VALUES ('{"PI":3.14}'); UPDATE jdemo2 SET variant1 = PARSE_JSON(varchar1);该查询表明
TO_JSON
和PARSE_JSON
在概念上是互逆函数:SELECT varchar1, PARSE_JSON(varchar1), variant1, TO_JSON(variant1), PARSE_JSON(varchar1) = variant1, TO_JSON(variant1) = varchar1 FROM jdemo2; +-------------+----------------------+--------------+-------------------+---------------------------------+------------------------------+ | VARCHAR1 | PARSE_JSON(VARCHAR1) | VARIANT1 | TO_JSON(VARIANT1) | PARSE_JSON(VARCHAR1) = VARIANT1 | TO_JSON(VARIANT1) = VARCHAR1 | |-------------+----------------------+--------------+-------------------+---------------------------------+------------------------------| | {"PI":3.14} | { | { | {"PI":3.14} | True | True | | | "PI": 3.14 | "PI": 3.14 | | | | | | } | } | | | | +-------------+----------------------+--------------+-------------------+---------------------------------+------------------------------+但是,这些功能并不完全是互逆的;键值对的空格或顺序差异可能会阻止输出与输入匹配。例如:
SELECT TO_JSON(PARSE_JSON('{"b":1,"a":2}')), TO_JSON(PARSE_JSON('{"b":1,"a":2}')) = '{"b":1,"a":2}', TO_JSON(PARSE_JSON('{"b":1,"a":2}')) = '{"a":2,"b":1}' ; +--------------------------------------+--------------------------------------------------------+--------------------------------------------------------+ | TO_JSON(PARSE_JSON('{"B":1,"A":2}')) | TO_JSON(PARSE_JSON('{"B":1,"A":2}')) = '{"B":1,"A":2}' | TO_JSON(PARSE_JSON('{"B":1,"A":2}')) = '{"A":2,"B":1}' | |--------------------------------------+--------------------------------------------------------+--------------------------------------------------------| | {"a":2,"b":1} | False | True | +--------------------------------------+--------------------------------------------------------+--------------------------------------------------------+尽管
PARSE_JSON
和TO_VARIANT
都可以接受一个字符串并返回一个变体,但它们并不等效。下面的代码使用PARSE_JSON
更新一列,使用TO_VARIANT
更新另一列。(对列variant1
的更新是不必要的,因为它之前是使用相同的函数调用更新的;但是,下面的代码会再次更新它,以便您可以并排查看调用哪些函数来更新列)。UPDATE jdemo2 SET variant1 = PARSE_JSON(varchar1), variant2 = TO_VARIANT(varchar1);下面的查询显示
PARSE_JSON
的输出和TO_VARIANT
的输出不同。除了空格中的细微差异外,引号也存在显著差异。SELECT variant1, variant2, variant1 = variant2 FROM jdemo2; +--------------+-----------------+---------------------+ | VARIANT1 | VARIANT2 | VARIANT1 = VARIANT2 | |--------------+-----------------+---------------------| | { | "{\"PI\":3.14}" | False | | "PI": 3.14 | | | | } | | | +--------------+-----------------+---------------------+