一、概述
默认情况下,SQLite 支持十五个函数和两个运算符来处理 JSON 值。还有两个表值函数 可用于分解 JSON 字符串。
有 15 个标量函数和运算符:
- json(json)
- json_array(value1,value2,...)
-
json_array_length(json)
json_array_length(json,path) - json_extract(json,path,...)
- json -> path
- json ->> path
- json_insert(json,path,value,...)
- json_object(label1,value1,...)
- json_patch(json1,json2)
- json_remove(json,path,...)
- json_replace(json,path,value,...)
- json_set(json,path,value,...)
-
json_type(json)
json_type(json,path) - json_valid(json)
- json_quote(value)
有两个聚合 SQL 函数:
- json_group_array(value)
- json_group_object(name,value)
这两个表值函数是:
2.支持JSON编译
从 SQLite 版本 3.38.0 (2022-02-22) 开始,JSON 函数和运算符默认内置到 SQLite 中。可以通过添加 -DSQLITE_OMIT_JSON 编译时选项来省略它们。在版本 3.38.0 之前,JSON 函数是一个扩展,只有在包含 -DSQLITE_ENABLE_JSON1 编译时选项时才会包含在构建中。换句话说,JSON 函数从选择加入 SQLite 3.37.2 及更早版本到选择退出 SQLite 3.38.0 及更高版本。
三、界面概述
SQLite 将 JSON 存储为普通文本。向后兼容性约束意味着 SQLite 只能存储 NULL、整数、浮点数、文本和 BLOB 的值。不可能添加第六种“JSON”类型。
SQLite(目前)不支持 JSON 的二进制编码。实验一直无法找到比纯文本编码更小或更快的二进制编码。(目前的实现以超过 1 GB/s 的速度解析 JSON 文本。)如果所有 JSON 函数的任何参数是 BLOB,目前都会抛出错误,因为 BLOB 是为将来的增强功能保留的,其中 BLOB 将存储 JSON 的二进制编码。
3.1. JSON 参数
对于接受 JSON 作为第一个参数的函数,该参数可以是 JSON 对象、数组、数字、字符串或 null。SQLite 数值和 NULL 值分别被解释为 JSON 数字和空值。SQLite 文本值可以理解为 JSON 对象、数组或字符串。如果将不是格式良好的 JSON 对象、数组或字符串的 SQLite 文本值传递给 JSON 函数,该函数通常会抛出错误。(此规则的例外是json_valid()和 json_quote()。)
为了确定有效性,忽略 JSON 输入中的前导和尾随空格。根据 JSON 规范,内部空白也会被忽略。这些例程完全接受 rfc-7159 JSON 语法 ——不多也不少。
3.2. 路径参数
对于接受 PATH 参数的函数,该 PATH 必须格式正确,否则该函数将抛出错误。格式正确的 PATH 是一个文本值,它以一个“$”字符开头,后跟零个或多个“ .objectlabel ”或“[ arrayindex ]”实例。
arrayindex通常是一个非负整数N。在这种情况下,所选的数组元素是数组的第N个元素,从左侧的零开始。arrayindex也可以是“ #- N ”的形式,在这种情况下,选择的元素是从右边数第N个。数组的最后一个元素是“ #-1 ”。将“#”字符视为“数组中的元素数”。然后表达式“#-1”的计算结果为对应于数组中最后一项的整数。有时数组索引只是#字符很有用,
- json_set('[0,1,2]','$[#]','new') → '[0,1,2,"new"]'
3.3. VALUE 参数
对于接受“ value ”参数(也显示为“ value1 ”和“ value2 ”)的函数,这些参数通常被理解为被引用的文字字符串,并在结果中成为 JSON 字符串值。即使输入值字符串看起来像格式正确的 JSON,它们在结果中仍被解释为文字字符串。
但是,如果值参数直接来自另一个 JSON 函数的结果或来自-> 运算符(而不是->> 运算符),则该参数被理解为实际的 JSON 并且插入完整的 JSON 而不是引用细绳。
例如,在以下对 json_object() 的调用中,值 参数看起来像一个格式正确的 JSON 数组。但是,因为它只是普通的 SQL 文本,所以它被解释为文字字符串并作为带引号的字符串添加到结果中:
- json_object('ex','[52,3.14159]') → '{"ex":"[52,3.14159]"}'
- json_object('ex',('52,3.14159]'->>'$')) → '{"ex":"[52,3.14159]"}'
但是,如果外部 json_object() 调用中的值参数是另一个 JSON 函数(如json()或json_array() )的结果,那么该值将被理解为实际的 JSON 并按如下方式插入:
- json_object('ex',json('[52,3.14159]')) → '{"ex":[52,3.14159]}'
- json_object('ex',json_array(52,3.14159)) → '{"ex":[52,3.14159]}'
- json_object('ex','[52,3.14159]'->'$') → '{"ex":[52,3.14159]}'
需要明确的是:“ json ”参数总是被解释为 JSON,无论该参数的值来自何处。但是,如果这些参数直接来自另一个 JSON 函数或-> 运算符,则“值”参数只会被解释为 JSON 。
3.4. 兼容性
此 JSON 库的当前实现使用递归下降解析器。为了避免使用过多的堆栈空间,任何超过 2000 层嵌套的 JSON 输入都被视为无效。RFC-7159 第 9 节允许对 JSON 的兼容实现限制嵌套深度 。
四、功能详情
以下部分提供了有关各种 JSON 函数和运算符的操作的更多详细信息:
4.1. json() 函数
json(X) 函数验证其参数 X 是否为有效的 JSON 字符串,并返回该 JSON 字符串的缩小版本(删除了所有不必要的空格)。如果 X 不是格式正确的 JSON 字符串,则此例程会引发错误。
换句话说,此函数将看起来像 JSON 的原始文本转换为实际的 JSON,以便它可以传递到其他一些 json 函数的值参数 中,并将被解释为 JSON 而不是字符串。此函数不适用于测试特定字符串是否为格式正确的 JSON - 请使用下面的json_valid()例程来完成该任务。
如果 json(X) 的参数 X 包含具有重复标签的 JSON 对象,则是否保留重复项是未定义的。当前的实现保留了重复项。但是,此例程的未来增强可能会选择静默删除重复项。
例子:
- json(' { "this" : "is", "a": [ "test" ] } ') → '{"this":"is","a":["test"]}'
4.2. json_array() 函数
json_array() SQL 函数接受零个或多个参数并返回由这些参数组成的格式正确的 JSON 数组。如果 json_array() 的任何参数是 BLOB,则会抛出错误。
SQL 类型 TEXT 的参数通常会转换为带引号的 JSON 字符串。但是,如果参数是另一个 json1 函数的输出,则它会存储为 JSON。这允许嵌套调用 json_array() 和json_object()。json()函数也可用于强制将字符串识别为 JSON 。
例子:
- json_array(1,2,'3',4) → '[1,2,"3",4]'
- json_array('[1,2]') → '["[1,2]"]'
- json_array(json_array(1,2)) → '[[1,2]]'
- json_array(1,null,'3','[4,5]','{"six":7.7}') → '[1,null,"3","[4,5]","{\"six\":7.7}"]'
- json_array(1,null,'3',json('[4,5]'),json('{"six":7.7}')) → '[1,null,"3",[4,5],{"six":7.7}]'
4.3. json_array_length() 函数
json_array_length(X) 函数返回 JSON 数组 X 中元素的数量,如果 X 是数组以外的某种 JSON 值,则返回 0。json_array_length(X,P) 将数组定位到 X 内的路径 P 并返回该数组的长度,如果路径 P 找到一个元素或 X 不是 JSON 数组,则返回 0,如果路径 P 没有找到任何元素,则返回 NULL X。如果 X 不是格式正确的 JSON 或者 P 不是格式正确的路径,则会抛出错误。
例子:
- json_array_length('[1,2,3,4]') → 4
- json_array_length('[1,2,3,4]', '$') → 4
- json_array_length('[1,2,3,4]', '$[2]') → 0
- json_array_length('{"one":[1,2,3]}') → 0
- json_array_length('{"one":[1,2,3]}', '$.one') → 3
- json_array_length('{"one":[1,2,3]}', '$.two') → NULL
4.4. json_extract() 函数
json_extract(X,P1,P2,...) 从 X 处的格式良好的 JSON 中提取并返回一个或多个值。如果仅提供单个路径 P1,则结果的 SQL 数据类型对于 JSON 为 NULL JSON 数值为 null、INTEGER 或 REAL,JSON 假值为 INTEGER 零,JSON 真值为 INTEGER 1,JSON 字符串值的去引号文本,以及 JSON 对象和数组值的文本表示。如果有多个路径参数(P1、P2 等),则此例程返回 SQLite 文本,这是一个格式正确的 JSON 数组,包含各种值。
例子:
- json_extract('{"a":2,"c":[4,5,{"f":7}]}', '$') → '{"a":2,"c":[4,5,{"f":7}]}'
- json_extract('{"a":2,"c":[4,5,{"f":7}]}', '$.c') → '[4,5,{"f":7}]'
- json_extract('{"a":2,"c":[4,5,{"f":7}]}', '$.c[2]') → '{"f":7}'
- json_extract('{"a":2,"c":[4,5,{"f":7}]}', '$.c[2].f') → 7
- json_extract('{"a":2,"c":[4,5],"f":7}','$.c','$.a') → '[[4,5],2]'
- json_extract('{"a":2,"c":[4,5],"f":7}','$.c[#-1]') → 5
- json_extract('{"a":2,"c":[4,5,{"f":7}]}', '$.x') → NULL
- json_extract('{"a":2,"c":[4,5,{"f":7}]}', '$.x', '$.a') → '[null,2]'
- json_extract('{"a":"xyz"}', '$.a') → 'xyz'
- json_extract('{"a":null}', '$.a') → NULL
SQLite 中的 json_extract() 函数与 MySQL 中的 json_extract() 函数之间存在细微的不兼容性。MySQL 版本的 json_extract() 总是返回 JSON。SQLite 版本的 json_extract() 仅在有两个或多个 PATH 参数(因为结果是一个 JSON 数组)或单个 PATH 参数引用数组或对象时才返回 JSON。在 SQLite 中,如果 json_extract() 只有一个 PATH 参数并且该 PATH 引用 JSON null 或字符串或数值,则 json_extract() 返回相应的 SQL NULL、TEXT、INTEGER 或 REAL 值。
MySQL json_extract() 和 SQLite json_extract() 之间的区别实际上只有在访问 JSON 中的单个值(字符串或 NULL)时才会突出。下表显示了差异:
Operation | SQLite Result | MySQL Result |
---|---|---|
json_extract('{"a":null,"b":"xyz"}','$.a') | NULL | 'null' |
json_extract('{"a":null,"b":"xyz"}','$.b') | 'xyz' | '"xyz"' |
4.5. -> 和 ->> 运算符
从 SQLite 版本 3.38.0 (2022-02-22) 开始,-> 和 ->> 运算符可用于提取 JSON 的子组件。-> 和 ->> 运算符的 SQLite 实现努力与 MySQL 和 PostgreSQL 兼容。-> 和 ->> 运算符将 JSON 字符串作为其左操作数,并将 PATH 表达式或对象字段标签或数组索引作为其右操作数。-> 运算符返回所选子组件的 JSON 表示形式,如果该子组件不存在,则返回 NULL。->> 运算符返回表示所选子组件的 SQL TEXT、INTEGER、REAL 或 NULL 值,如果子组件不存在,则返回 NULL。
-> 和 ->> 运算符都选择左侧 JSON 的相同子组件。区别在于 -> 始终返回该子组件的 JSON 表示,而 ->> 运算符始终返回该子组件的 SQL 表示。因此,这些运算符与双参数json_extract()函数调用略有不同。当且仅当子组件是 JSON 数组或对象时,使用两个参数调用 json_extract() 将返回子组件的 JSON 表示,如果子组件是 JSON null、字符串或数值。
-> 和 ->> 运算符的右侧操作数可以是格式正确的 JSON 路径表达式。这是 MySQL 使用的形式。为了与 PostgreSQL 兼容,-> 和 ->> 运算符也接受文本标签或整数作为它们的右手操作数。如果右操作数是文本标签 X,则它被解释为 JSON 路径“$.X”。如果右操作数是整数值 N,则它被解释为 JSON 路径“$[N]”。
例子:
- '{"a":2,"c":[4,5,{"f":7}]}' -> '$' → '{"a":2,"c":[4,5,{"f":7}]}'
- '{"a":2,"c":[4,5,{"f":7}]}' -> '$.c' → '[4,5,{"f":7}]'
- '{"a":2,"c":[4,5,{"f":7}]}' -> 'c' → '[4,5,{"f":7}]'
- '{"a":2,"c":[4,5,{"f":7}]}' -> '$.c[2]' → '{"f":7}'
- '{"a":2,"c":[4,5,{"f":7}]}' -> '$.c[2].f' → '7'
- '{"a":2,"c":[4,5],"f":7}' -> '$.c[#-1]' → '5'
- '{"a":2,"c":[4,5,{"f":7}]}' -> '$.x' → NULL
- '[11,22,33,44]' -> 3 → '44'
- '[11,22,33,44]' ->> 3 → 44
- '{"a":"xyz"}' -> '$.a' → '"xyz"'
- '{"a":"xyz"}' ->> '$.a' → 'xyz'
- '{"a":null}' -> '$.a' → 'null'
- '{"a":null}' ->> '$.a' → NULL
4.6. json_insert()、json_replace 和 json_set() 函数
json_insert()、json_replace 和 json_set() 函数都将单个 JSON 值作为它们的第一个参数,后跟零个或多对路径和值参数,并返回一个新的 JSON 字符串,该字符串是通过路径更新输入 JSON 形成的/值对。这些函数的不同之处仅在于它们如何处理创建新值和覆盖先前存在的值。
Function | Overwrite if already exists? | Create if does not exist? |
---|---|---|
json_insert() | No | Yes |
json_replace() | Yes | No |
json_set() | Yes | Yes |
json_insert()、json_replace() 和 json_set() 函数始终采用奇数个参数。第一个参数始终是要编辑的原始 JSON。后续参数成对出现,每对中的第一个元素是路径,第二个元素是要在该路径上插入、替换或设置的值。
编辑按顺序从左到右进行。先前编辑引起的更改会影响后续编辑的路径搜索。
如果路径/值对的值是 SQLite TEXT 值,那么它通常作为带引号的 JSON 字符串插入,即使该字符串看起来像有效的 JSON。但是,如果该值是另一个 json1 函数(例如json()或json_array()或json_object())的结果,或者如果它是-> 运算符的结果,则它被解释为 JSON 并作为 JSON 插入保留其所有子结构。作为 ->> 运算符结果的值 始终被解释为 TEXT 并作为 JSON 字符串插入,即使它们看起来像有效的 JSON。
如果第一个 JSON 参数格式不正确或任何 PATH 参数格式不正确或任何参数是 BLOB,这些例程将抛出错误。
要将元素追加到数组的末尾,请使用数组索引为“#”的 json_insert()。例子:
- json_insert('[1,2,3,4]','$[#]',99) → '[1,2,3,4,99]'
- json_insert('[1,[2,3],4]','$[1][#]',99) → '[1,[2,3,99],4]'
其他例子:
- json_insert('{"a":2,"c":4}', '$.a', 99) → '{"a":2,"c":4}'
- json_insert('{"a":2,"c":4}', '$.e', 99) → '{"a":2,"c":4,"e":99}'
- json_replace('{"a":2,"c":4}', '$.a', 99) → '{"a":99,"c":4}'
- json_replace('{"a":2,"c":4}', '$.e', 99) → '{"a":2,"c":4}'
- json_set('{"a":2,"c":4}', '$.a', 99) → '{"a":99,"c":4}'
- json_set('{"a":2,"c":4}', '$.e', 99) → '{"a":2,"c":4,"e":99}'
- json_set('{"a":2,"c":4}', '$.c', '[97,96]') → '{"a":2,"c":"[97,96]"}'
- json_set('{"a":2,"c":4}', '$.c', json('[97,96]')) → '{"a":2,"c":[97,96]}'
- json_set('{"a":2,"c":4}', '$.c', json_array(97,96)) → '{"a":2,"c":[97,96]}'
4.7. json_object() 函数
json_object() SQL 函数接受零对或多对参数,并返回由这些参数组成的格式良好的 JSON 对象。每对的第一个参数是标签,每对的第二个参数是值。如果 json_object() 的任何参数是 BLOB,则会抛出错误。
json_object() 函数目前允许重复标签而无需抱怨,尽管这可能会在未来的增强中改变。
SQL 类型 TEXT 的参数通常会转换为带引号的 JSON 字符串,即使输入文本是格式正确的 JSON。但是,如果参数是另一个 JSON 函数或-> 运算符(但不是->> 运算符)的直接结果,那么它会被视为 JSON,并且保留其所有 JSON 类型信息和子结构。这允许嵌套调用 json_object() 和json_array()。json()函数也可用于强制将字符串识别为 JSON 。
例子:
- json_object('a',2,'c',4) → '{"a":2,"c":4}'
- json_object('a',2,'c','{e:5}') → '{"a":2,"c":"{e:5}"}'
- json_object('a',2,'c',json_object('e',5)) → '{"a":2,"c":{"e":5}}'
4.8. json_patch() 函数
json_patch(T,P) SQL 函数运行 RFC-7396 MergePatch 算法以针对输入 T 应用补丁 P。返回 T 的补丁副本。
MergePatch 可以添加、修改或删除 JSON 对象的元素,因此对于 JSON 对象, json_patch() 例程是json_set()和json_remove()的通用替代品。但是,MergePatch 将 JSON Array 对象视为原子的。MergePatch 不能附加到数组,也不能修改数组的单个元素。它只能作为一个单元插入、替换或删除整个数组。因此,在处理包含数组的 JSON,尤其是具有大量子结构的数组时,json_patch() 的用处不大。
例子:
- json_patch('{"a":1,"b":2}','{"c":3,"d":4}') → '{"a":1,"b":2,"c":3,"d":4}'
- json_patch('{"a":[1,2],"b":2}','{"a":9}') → '{"a":9,"b":2}'
- json_patch('{"a":[1,2],"b":2}','{"a":null}') → '{"b":2}'
- json_patch('{"a":1,"b":2}','{"a":9,"b":null,"c":8}') → '{"a":9,"c":8}'
- json_patch('{"a":{"x":1,"y":2},"b":3}','{"a":{"y":9},"c":8}') → '{"a":{"x":1,"y":9},"b":3,"c":8}'
4.9. json_remove() 函数
json_remove(X,P,...) 函数采用单个 JSON 值作为其第一个参数,后跟零个或多个路径参数。json_remove(X,P,...) 函数返回 X 参数的副本,其中删除了路径参数标识的所有元素。选择在 X 中找不到的元素的路径将被静默忽略。
删除顺序从左到右发生。先前删除引起的更改会影响后续参数的路径搜索。
如果在没有路径参数的情况下调用 json_remove(X) 函数,那么它将返回重新格式化的输入 X,并删除多余的空格。
如果第一个参数不是格式正确的 JSON 或者任何后面的参数不是格式正确的路径,或者任何参数是 BLOB,json_remove() 函数会抛出错误。
例子:
- json_remove('[0,1,2,3,4]','$[2]') → '[0,1,3,4]'
- json_remove('[0,1,2,3,4]','$[2]','$[0]') → '[1,3,4]'
- json_remove('[0,1,2,3,4]','$[0]','$[2]') → '[1,2,4]'
- json_remove('[0,1,2,3,4]','$[#-1]','$[0]') → '[1,2,3]'
- json_remove('{"x":25,"y":42}') → '{"x":25,"y":42}'
- json_remove('{"x":25,"y":42}','$.z') → '{"x":25,"y":42}'
- json_remove('{"x":25,"y":42}','$.y') → '{"x":25}'
- json_remove('{"x":25,"y":42}','$') → NULL
4.10. json_type() 函数
json_type(X)函数返回X的最外层元素的“类型”。json_type(X,P)函数返回路径P选择的X中元素的“类型”。json_type返回的“类型” () 是以下 SQL 文本值之一:“null”、“true”、“false”、“integer”、“real”、“text”、“array”或“object”。如果json_type(X,P)中的路径P选择了X中不存在的元素,那么这个函数返回NULL。
如果 json_type() 函数的任何参数格式不正确或者是 BLOB,则会抛出错误。
例子:
- json_type('{"a":[2,3.5,true,false,null,"x"]}') → 'object'
- json_type('{"a":[2,3.5,true,false,null,"x"]}','$') → 'object'
- json_type('{"a":[2,3.5,true,false,null,"x"]}','$.a') → 'array'
- json_type('{"a":[2,3.5,true,false,null,"x"]}','$.a[0]') → 'integer'
- json_type('{"a":[2,3.5,true,false,null,"x"]}','$.a[1]') → 'real'
- json_type('{"a":[2,3.5,true,false,null,"x"]}','$.a[2]') → 'true'
- json_type('{"a":[2,3.5,true,false,null,"x"]}','$.a[3]') → 'false'
- json_type('{"a":[2,3.5,true,false,null,"x"]}','$.a[4]') → 'null'
- json_type('{"a":[2,3.5,true,false,null,"x"]}','$.a[5]') → 'text'
- json_type('{"a":[2,3.5,true,false,null,"x"]}','$.a[6]') → NULL
4.11. json_valid() 函数
如果参数 X 是格式良好的 JSON,则 json_valid(X) 函数返回 1,如果参数 X 不是格式良好的 JSON,则返回 0。
例子:
- json_valid('{"x":35}') → 1
- json_valid('{"x":35') → 0
4.12. json_quote() 函数
json_quote(X) 函数将 SQL 值 X(数字或字符串)转换为其对应的 JSON 表示形式。如果 X 是另一个 JSON 函数返回的 JSON 值,则此函数是空操作。
例子:
- json_quote(3.14159) → 3.14159
- json_quote('verdant') → '"verdant"'
- json_quote('[1]') → '"[1]"'
- json_quote(json('[1]')) → '[1]'
- json_quote('[1,') → '"[1"'
4.13. json_group_array() 和 json_group_object() 聚合 SQL 函数
json_group_array(X) 函数是一个 聚合 SQL 函数,它返回一个由聚合中所有 X 值组成的 JSON 数组。同样,json_group_object(NAME,VALUE) 函数返回一个由聚合中的所有 NAME/VALUE 对组成的 JSON 对象。
4.14. json_each() 和 json_tree() 表值函数
json_each(X) 和 json_tree(X)表值函数遍历作为第一个参数提供的 JSON 值,并为每个元素返回一行。json_each(X) 函数只遍历顶级数组或对象的直接子元素,或者如果顶级元素是原始值,则只遍历顶级元素本身。json_tree(X) 函数从顶级元素开始递归遍历 JSON 子结构。
json_each(X,P) 和 json_tree(X,P) 函数的工作方式与它们的单参数对应函数一样,只是它们将路径 P 标识的元素视为顶级元素。
json_each() 和 json_tree() 返回的表的架构如下:
CREATE TABLE json_tree( key ANY, -- key for current element relative to its parent value ANY, -- value for the current element type TEXT, -- 'object','array','string','integer', etc. atom ANY, -- value for primitive types, null for array & object id INTEGER, -- integer ID for this element parent INTEGER, -- integer ID for the parent of this element fullkey TEXT, -- full path describing the current element path TEXT, -- path to the container of the current row json JSON HIDDEN, -- 1st input parameter: the raw JSON root TEXT HIDDEN -- 2nd input parameter: the PATH at which to start );
“键”列是 JSON 数组元素的整数数组索引和 JSON 对象元素的文本标签。在所有其他情况下,键列为 NULL。
“原子”列是对应于原始元素的 SQL 值——除了 JSON 数组和对象之外的元素。对于 JSON 数组或对象,“atom”列为 NULL。“值”列与原始 JSON 元素的“原子”列相同,但采用数组和对象的文本 JSON 值。
“类型”列是根据类型从 ('null', 'true', 'false', 'integer', 'real', 'text', 'array', 'object') 中获取的 SQL 文本值当前的 JSON 元素。
“id”列是一个整数,用于标识完整 JSON 字符串中的特定 JSON 元素。“id”整数是一个内部管家编号,其计算可能会在未来的版本中发生变化。唯一的保证是每一行的“id”列都不同。
json_each() 的“父”列始终为 NULL。对于 json_tree(),“parent”列是当前元素父级的“id”整数,或者对于顶级 JSON 元素或第二个参数中根路径标识的元素为 NULL。
“fullkey”列是在原始 JSON 字符串中唯一标识当前行元素的文本路径。即使“root”参数提供了替代起点,也会返回真正顶级元素的完整键。
“路径”列是指向包含当前行的数组或对象容器的路径,或者在迭代从原始类型开始并因此仅提供单行输出的情况下指向当前行的路径。
4.14.1. 使用 json_each() 和 json_tree() 的示例
假设表“CREATE TABLE user(name,phone)”将零个或多个电话号码作为 JSON 数组对象存储在 user.phone 字段中。要查找电话号码带 704 区号的所有用户:
SELECT DISTINCT user.name FROM user, json_each(user.phone) WHERE json_each.value LIKE '704-%';
Now suppose the user.phone field contains plain text if the user has only a single phone number and a JSON array if the user has multiple phone numbers. The same question is posed: "Which users have a phone number in the 704 area code?" But now the json_each() function can only be called for those users that have two or more phone numbers since json_each() requires well-formed JSON as its first argument:
SELECT name FROM user WHERE phone LIKE '704-%' UNION SELECT user.name FROM user, json_each(user.phone) WHERE json_valid(user.phone) AND json_each.value LIKE '704-%';
Consider a different database with "CREATE TABLE big(json JSON)". To see a complete line-by-line decomposition of the data:
SELECT big.rowid, fullkey, value FROM big, json_tree(big.json) WHERE json_tree.type NOT IN ('object','array');
In the previous, the "type NOT IN ('object','array')" term of the WHERE clause suppresses containers and only lets through leaf elements. The same effect could be achieved this way:
SELECT big.rowid, fullkey, atom FROM big, json_tree(big.json) WHERE atom IS NOT NULL;
假设 BIG 表中的每个条目都是一个 JSON 对象,具有作为唯一标识符的“$.id”字段和可以是深度嵌套对象的“$.partlist”字段。您想要在其“$.partlist”中的任何位置找到包含对 uuid“6fa5181e-5721-11e5-a04e-57f3d7b32808”的一个或多个引用的每个条目的 ID。
SELECT DISTINCT json_extract(big.json,'$.id') FROM big, json_tree(big.json, '$.partlist') WHERE json_tree.key='uuid' AND json_tree.value='6fa5181e-5721-11e5-a04e-57f3d7b32808';