在日常应用中,我们可能会对一些json字符的数据进行数据获取处理,json_table是常用的函数之一,它可以将json字符数据处理为表数据的形式进行展现。
以下解释来源于Oracle官网SQL/JSON Function JSON_TABLE:
SQL/JSON函数json_table将特定的JSON数据投射到各种SQL数据类型的列中。
可以使用它将JSON文档的部分映射到新的虚拟表的行和列中,也可以将其视为内联视图。
可以将这个虚拟表插入到一个预先存在的数据库表中,或者可以使用sql(例如在连接表达式中)查询它。
json_table的一个常见用途是创建JSON数据的视图。可以像使用任何表或视图一样使用这样的视图。
在JSON数据上定义视图实际上是将一种模式映射到该数据上。这种映射是事后的:
可以定义和创建底层JSON数据,而无需考虑模式或任何特定的使用模式。
首先是数据,然后是模式。这种模式(映射)对可以存储在数据库中的JSON文档的类型没有限制(除了格式良好的JSON数据)。视图只公开符合定义视图的映射(模式)的数据。要更改模式,只需重新定义视图---无需重新组织底层JSON数据。
在SQL FROM子句中使用json_table。它是一个行源:它为行路径表达式(行模式)选择的每个JSON值生成一行虚拟数据。每个生成行的列由columns子句的列路径表达式定义。
通常,json_table调用与FROM列表中的源表进行隐式横向连接,源表的每一行都包含一个JSON文档,用作函数的输入。
Json_table生成零个或多个新行,这是通过对输入文档计算行路径表达式来确定的。
json_table的第一个参数是一个SQL表达式。它可以是表或视图列值、PL/SQL变量或具有适当类型转换的绑定变量。计算表达式的结果用作计算行路径表达式的上下文项。
json_table的第二个参数是SQL/JSON行路径表达式,后面跟着处理行的可选错误子句和(必需的)COLUMNS子句,它定义要创建的虚拟表的列。没有
RETURNING
子句。json_table有两个级别的错误处理,对应于两个级别的路径表达式:行和列。
出现时,列错误处理程序将覆盖行级错误处理程序。
两个级别的默认错误处理程序都是NULL ON ERROR。
作为传递上下文项参数和行路径表达式的替代方法,可以使用简单的点表示法语法。
(仍然可以使用错误子句,并且仍然需要COLUMNS子句。)
点表示法指定一个表或视图列,以及指向目标JSON数据的简单路径。
例如,这两个查询是等价的:
sqljson_table(t.j, '$.ShippingInstructions.Phone[*]' ...) json_table(t.j.ShippingInstructions.Phone[*] ...)
如果行路径表达式仅为'$',且针对整个文档,则可以省略路径部分。
这些查询是等价的:
sqljson_table(t.j, '$' ...) json_table(t.j ...)
JSON_TABLE相关结构语法:
Description of the illustration json_table.eps
Description of the illustration json_table_on_error_clause.eps
Description of the illustration json_table_on_empty_clause.eps
Description of the illustration json_columns_clause.eps
Description of the illustration json_column_definition.eps
Description of the illustration json_exists_column.eps
Description of the illustration json_query_column.eps
Description of the illustration json_value_column.eps
Description of the illustration json_nested_path.eps
Description of the illustration ordinality_column.eps
Description of the illustration json_path.eps
Description of the illustration json_relative_object_access.eps
Description of the illustration nested_clause.eps
假如有一个json字符串(文中使用案例)为:
html
{
"id": 1,
"name": "v1",
"dsc": [
{
"id": 1,
"note": "test"
},
{
"id": 2,
"note": "test2"
}
],
"node": {
"id": "sdjfsf1",
"name": "test1"
}
}
1.将json字符串中的普通值解析映射为表数据
sql
select * from json_table('{
"id": 1,
"name": "v1",
"dsc": [
{
"id": 1,
"note": "test"
},
{
"id": 2,
"note": "test2"
}
],
"node": {
"id": "sdjfsf1",
"name": "test1"
}
}','$' COLUMNS (
id number path '$.id',
name varchar2(50) path '$.name'
));

2.将json字符串中内层的json对象值(本身需要的值为json字符串)解析映射为表数据,以普通字符串值的映射方式将无法解析到值,需结合使用FORMAT JSON子句
sql
select * from json_table('{
"id": 1,
"name": "v1",
"dsc": [
{
"id": 1,
"note": "test"
},
{
"id": 2,
"note": "test2"
}
],
"node": {
"id": "sdjfsf1",
"name": "test1"
}
}','$' COLUMNS (
id number path '$.id',
name varchar2(50) path '$.name',
dsc clob format json path '$.dsc'
));

3.json字符串解析映射存在内层循环时,需使用NESTED子句
sql
select * from json_table('{
"id": 1,
"name": "v1",
"dsc": [
{
"id": 1,
"note": "test"
},
{
"id": 2,
"note": "test2"
}
],
"node": {
"id": "sdjfsf1",
"name": "test1"
}
}','$' COLUMNS (
id number path '$.id',
name varchar2(50) path '$.name',
NESTED PATH '$.dsc[*]'
COLUMNS(
dscid number path '$.id',
dscnote varchar2(50) path '$.note'
)
));

4.将json字符串中的子json字符串解析映射为表数据,需结合JSON_QUERY函数使用(当字符串过长需结合使用JSON_QUERY的RETURNING子句)
sql
select * from json_table(JSON_QUERY('{
"id": 1,
"name": "v1",
"dsc": [
{
"id": 1,
"note": "test"
},
{
"id": 2,
"note": "test2"
}
],
"node": {
"id": "sdjfsf1",
"name": "test1"
}
}','$.node' returning clob),'$' COLUMNS (
id varchar2(20) path '$.id',
name varchar2(50) path '$.name'
));

当子json字符串为数组时
sql
select * from json_table(JSON_QUERY('{
"id": 1,
"name": "v1",
"dsc": [
{
"id": 1,
"note": "test"
},
{
"id": 2,
"note": "test2"
}
],
"node": {
"id": "sdjfsf1",
"name": "test1"
}
}','$.dsc' returning clob),'$[*]' COLUMNS (
id varchar2(20) path '$.id',
note varchar2(50) path '$.note'
));
