Oracle函数JSON_TABLE使用

在日常应用中,我们可能会对一些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数据的简单路径。

例如,这两个查询是等价的:

sql 复制代码
json_table(t.j, '$.ShippingInstructions.Phone[*]' ...)

json_table(t.j.ShippingInstructions.Phone[*] ...)

如果行路径表达式仅为'$',且针对整个文档,则可以省略路径部分。

这些查询是等价的:

sql 复制代码
json_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'
));
相关推荐
paopaokaka_luck几秒前
智能推荐社交分享小程序(websocket即时通讯、协同过滤算法、时间衰减因子模型、热度得分算法)
数据库·vue.js·spring boot·后端·websocket·小程序
He.ZaoCha28 分钟前
函数-1-字符串函数
数据库·sql·mysql
二当家的素材网36 分钟前
Centos和麒麟系统如何每天晚上2点10分定时备份达梦数据库
linux·数据库·centos
白仑色43 分钟前
Oracle 存储过程、函数与触发器
数据库·oracle·数据库开发·存储过程·plsql编程
头发那是一根不剩了2 小时前
Spring Boot 多数据源切换:AbstractRoutingDataSource
数据库·spring boot·后端
草履虫建模2 小时前
Redis:高性能内存数据库与缓存利器
java·数据库·spring boot·redis·分布式·mysql·缓存
泊浮目3 小时前
未来数据库硬件-计算篇
数据库·云计算·操作系统
靖顺3 小时前
【OceanBase诊断调优】—— 执行计划显示分区 PARTITIONS[P0SP9] 如何查询是哪个分区?
数据库·oracle·oceanbase
KIDAKN4 小时前
MySQL 存储结构
数据库·mysql
Code季风4 小时前
SQL关键字快速入门:HAVING 分组后的条件过滤
数据库·sql·mysql