JSON 系列之4:JSON_VALUE

JSON_VALUE的作用,简单来说,就是从JSON到SQL:

SQL/JSON function JSON_VALUE selects JSON data and returns a SQL scalar or an instance of a user-defined SQL object type or SQL collection type (varray, nested table)

所以,JSON_VALUE是JSON到SQL间的桥梁。JSON_VALUE只返回一个标量。

JSON_VALUE需2个参数,第一个为JSON文档,第二个为JSON路径。

json 复制代码
{
  "PONumber" : 1,
  "Reference" : "MSULLIVA-20141102",
  "Requestor" : "Martha Sullivan",
  "User" : "MSULLIVA",
  "CostCenter" : "A50",
  "ShippingInstructions" :
  {
    "name" : "Martha Sullivan",
    "Address" :
    {
      "street" : "200 Sporting Green",
      "city" : "South San Francisco",
      "state" : "CA",
      "zipCode" : 99236,
      "country" : "United States of America"
    },
    "Phone" :
    [
      {
        "type" : "Office",
        "number" : "979-555-6598"
      }
    ]
  },
  "Special Instructions" : "Surface Mail",
  "LineItems" :
  [
    {
      "ItemNumber" : 1,
      "Part" :
      {
        "Description" : "Run Lola Run",
        "UnitPrice" : 19.95,
        "UPCCode" : 43396040144
      },
      "Quantity" : 7
    },
    {
      "ItemNumber" : 2,
      "Part" :
      {
        "Description" : "Felicia's Journey",
        "UnitPrice" : 19.95,
        "UPCCode" : 12236101345
      },
      "Quantity" : 1
    },
    {
      "ItemNumber" : 3,
      "Part" :
      {
        "Description" : "Lost and Found",
        "UnitPrice" : 19.95,
        "UPCCode" : 85391756323
      },
      "Quantity" : 8
    },
    {
      "ItemNumber" : 4,
      "Part" :
      {
        "Description" : "Karaoke: Rock & Roll Hits of 80's & 90's 8",
        "UnitPrice" : 19.95,
        "UPCCode" : 13023009592
      },
      "Quantity" : 8
    },
    {
      "ItemNumber" : 5,
      "Part" :
      {
        "Description" : "Theremin: An Electronic Odyssey",
        "UnitPrice" : 19.95,
        "UPCCode" : 27616864451
      },
      "Quantity" : 8
    }
  ]
}

我们使用标准的示例数据。

查看字段的数据类型:

sql 复制代码
SQL> select j.po_document."User".type() from j_purchaseorder j where j.po_document.PONumber = 1;

J.PO_DOCUMENT."USER".TYPE()                                                                         
----------------------------------------------------------------------------------------------------
string

SQL> select j.po_document.PONumber.type() from j_purchaseorder j where j.po_document.PONumber = 1;

J.PO_DOCUMENT.PONUMBER.TYPE()                                                                       
----------------------------------------------------------------------------------------------------
number

从下例可知,JSON文档的字段名是区分大小写的:

sql 复制代码
SQL> select json_value(po_document, '$.user') from j_purchaseorder where id =1;

JSON_VALUE(PO_DOCUMENT,'$.USER')
---------------------------------------


SQL> 
select json_value(po_document, '$.User') from j_purchaseorder where id =1;
-- 或
select json_value(po_document, '$.User') from j_purchaseorder where json_value(po_document, '$.PONumber') = 1;
-- 或
select json_value(po_document, '$.User') from j_purchaseorder j where j.po_document.PONumber = 1;
-- 或
select j.po_document."User" from j_purchaseorder j where j.po_document.PONumber = 1;

JSON_VALUE(PO_DOCUMENT,'$.USER')
--------------------------------------
MSULLIVA

其中的$是JSON路径表达式,语法说明参见17.2 SQL/JSON Path Expression Syntax

返回null的情形:

sql 复制代码
JSON_VALUE(PO_DOCUMENT,'$.SHIPPINGINSTRUCTIONS.LINEITEMS')                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 
---------------------------------------------------------------------------

这个也返回空,不明白:

sql 复制代码
select json_value(po_document, '$.LineItems[1].Part.UnitPrice') from j_purchaseorder where id =1;

出错的情形:

sql 复制代码
SQL> select json_value(po_document, '$.ShippingInstructions.name').type() from j_purchaseorder where id =1;
select json_value(po_document, '$.ShippingInstructions.name').type() from j_purchaseorder where id =1
                                                              *
ERROR at line 1:
ORA-22806: not an object or REF
Help: https://docs.oracle.com/error-help/db/ora-22806/

RETURNING 子句

文档说:

Use the RETURNING clause to specify the data type of the return value. If you omit this clause, then JSON_VALUE returns a value of type VARCHAR2(4000).

总之,返回的是SQL Data Type

例如,以下返回的是VARCHAR2(4000):

sql 复制代码
SQL> select json_value(po_document, '$.User') from j_purchaseorder where id =1;

JSON_VALUE(PO_DOCUMENT,'$.USER')                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              
---------------------------------------------
MSULLIVA

结合文档,以下证明其确实为VARCHAR2类型:

sql 复制代码
SQL> select dump(json_value(po_document, '$.User')) from j_purchaseorder where id =1;

DUMP(JSON_VALUE(PO_DOCUMENT,'$.USER'))                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        
--------------------------------------------------
Typ=1 Len=8: 77,83,85,76,76,73,86,65

指定RETURNING子句,以下显示了准确的数据类型:

sql 复制代码
create table test as select json_value(po_document, '$.User' RETURNING VARCHAR2(32)) as result from j_purchaseorder j where 1=2;

DESC test;

SQL> desc test;
 Name                                      Null?    Type
 ----------------------------------------- -------- ----------------------------
 RESULT                                             VARCHAR2(4000)

本例还可以转换为NUMBER类型:

sql 复制代码
create table test as select json_value(po_document, '$.User' RETURNING NUMBER) as result from j_purchaseorder j where 1=2;

SQL> desc test;
 Name                                      Null?    Type
 ----------------------------------------- -------- ----------------------------
 RESULT                                             NUMBER

返回BOOLEAN的例子,23ai才支持:

sql 复制代码
SQL> SELECT json_value(po_document, '$.AllowPartialShipment' RETURNING BOOLEAN) as aps
FROM j_purchaseorder j where j.po_document.AllowPartialShipment is not null;

APS  
-----
true

还可以将true/false转换为数字1/0:

sql 复制代码
SELECT json_value(po_document, '$.AllowPartialShipment'
                  RETURNING NUMBER
                  ALLOW BOOLEAN TO NUMBER CONVERSION)
  FROM j_purchaseorder j where j.po_document.AllowPartialShipment is not null;

JSON_VALUE(PO_DOCUMENT,'$.ALLOWPARTIALSHIPMENT'RETURNINGNUMBERALLOWBOOLEANTONUMBERCONVERSION)
---------------------------------------------------------------------------------------------
                                                                                            1

返回标量是最常见的场景,还可以返回User-Defined Object-Type or Collection-Type Instance

参考

相关推荐
Venuslite2 天前
从 Unexpected token < 到 Extra data:一次讲清 JSON 解析错误的排查思路
json
ClouGence6 天前
Oracle 数据同步为什么会出现数据不一致?长事务是常被忽略的原因
数据库·后端·oracle
疯狂SQL8 天前
手写高性能在线 JSON 工具|Web Worker 工程化打包 + 语法自动修复 + 多语言代码生成实战
typescript·json·next.js·web worker·前端性能优化·esbuild·源码实战
ClouGence12 天前
Oracle CDC 架构优化:从主库直连到 DataGuard 备库同步
数据库·后端·oracle
曹牧13 天前
Oracle EXPLAIN PLAN
数据库·oracle
贤时间13 天前
codex 助力oracle ebs 开发
数据库·oracle
秉承初心13 天前
PostgreSQL 数据性能瓶颈突破实战
数据库·postgresql·oracle
Curvatureflight13 天前
MySQL 深分页越来越慢?从 LIMIT OFFSET 改成游标分页
数据库·oracle
XZ-07000113 天前
MySQL事务
数据库·mysql·oracle
tiancaijiben13 天前
阿里云函数计算FC如何实现网站的定时任务与自动化
数据库·oracle·dba