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'
));
相关推荐
麦聪聊数据1 小时前
Web 原生架构如何重塑企业级数据库协作流?
数据库·sql·低代码·架构
未来之窗软件服务1 小时前
数据库优化提速(四)新加坡房产系统开发数据库表结构—仙盟创梦IDE
数据库·数据库优化·计算机软考
Goat恶霸詹姆斯2 小时前
mysql常用语句
数据库·mysql·oracle
大模型玩家七七3 小时前
梯度累积真的省显存吗?它换走的是什么成本
java·javascript·数据库·人工智能·深度学习
曾经的三心草3 小时前
redis-9-哨兵
数据库·redis·bootstrap
明哥说编程3 小时前
Dataverse自定义表查询优化:D365集成大数据量提速实战【索引配置】
数据库·查询优化·dataverse·dataverse自定义表·索引配置·d365集成·大数据量提速
xiaowu0803 小时前
C# 拆解 “显式接口实现 + 子类强类型扩展” 的设计思想
数据库·oracle
讯方洋哥3 小时前
HarmonyOS App开发——关系型数据库应用App开发
数据库·harmonyos
惊讶的猫4 小时前
Redis持久化介绍
数据库·redis·缓存
Apple_羊先森4 小时前
ORACLE数据库巡检SQL脚本--19、磁盘读次数最高的前5条SQL语句
数据库·sql·oracle