繁体   English   中英

使用 Oracle SQL 解析 Json - JSON_TABLE

[英]Parse Json using Oracle SQL - JSON_TABLE

我正在尝试使用 JSON_TABLE 解析 JSON。

Oracle DB版本12.1.0.2

{
 "Rownum": "1",
 "Name": "John",
 "AddressArray":["Address1", "Address2"],
 "TextObj":[{
             "mName" : "Carol",
             "lName" : "Cena"
            },
            {
             "mName" : "Mark",
             "lName" : "Karlo"
            }
           ]
}

尝试使用以下查询但未获得预期结果。

select * from json_Table(
'{
 "Rownum": "1",
 "Name": "John",
 "AddressArray":["Address1", "Address2"],
 "TextObj":[{"mName" : "Carol","lName" : "Cena"},
            {"mName" : "Mark","lName" : "Karlo"}
           ]
}', 
'$' columns (  rownr number path '$.Rownum', 
               name varchar2(100) path '$.Name', 
               nested path '$.TextObj[*]' columns  (mName varchar2(100) path '$.mName',
                                                    lName varchar2(100) path '$.lName'
                                                    ),
               nested path '$.AddressArray[*]' columns(AddressArray varchar2(100) path '$')
             )
);

Output 来自上述查询:

在此处输入图像描述

预期 output:

在此处输入图像描述

您可以链接几个json_table调用:

select j1.rnum, j1.name, j2.address, j3.mName, j3.lName
from (
  select '{
 "Rownum": "1",
 "Name": "John",
 "AddressArray":["Address1", "Address2"],
 "TextObj":[{
             "mName" : "Carol",
             "lName" : "Cena"
            },
            {
             "mName" : "Mark",
             "lName" : "Karlo"
            }
           ]
}' as str
  from dual
) t
outer apply json_table (
  t.str format json, '$'
  columns (
    rNum number path '$.Rownum',
    name varchar2(10) path '$.Name',
    addressArray varchar2(4000) format json path '$.AddressArray',
    textObj varchar2(4000) format json path '$.TextObj'
  )
) j1
outer apply json_table (
  j1.addressArray, '$[*]'
  columns (
    address varchar2(10) path '$'
  )
) j2
outer apply json_table (
  j1.textObj, '$[*]'
  columns (
    mName varchar2(10) path '$.mName',
    lName varchar2(10) path '$.lName'
  )
) j3

其中t只是一个内联视图,用于提供您的示例 JSON 作为str列,然后由第一个json_table处理。 这将获取行号和名称值,以及传递给第二个json_table的地址数组,以及传递给第三个 json_table 的文本json_table 这些从他们的 arrays 中产生值。

RNUM | NAME | ADDRESS  | MNAME | LNAME
---: | :--- | :------- | :---- | :----
   1 | John | Address1 | Carol | Cena 
   1 | John | Address1 | Mark  | Karlo
   1 | John | Address2 | Carol | Cena 
   1 | John | Address2 | Mark  | Karlo

db<>fiddle (18c,但在 12cR1 上验证)。

您似乎想要数组值的交叉连接(按rownumname分组)。 这不是标准的 JSON 结构,因此您不应该期望能够通过json_table的单个应用程序来做到这一点。

这是通过两次调用json_table来做到这一点的一种方法。 在第一次调用中,您使用嵌套路径仅获取名称,但仍保留地址 arrays。 在第二次调用中,您为第一次调用生成的每一行分别解包地址。

请注意在外部select中使用优化器提示。 这是必需的,因为没有它,优化器将尝试对横向连接( outer apply )进行非法的“取消嵌套”,然后抛出错误,而不是让查询保持原样。 (这是优化器的一个非常常见且令人讨厌的习惯:它尝试一些无效的东西,然后抱怨它。)

此外, rownum是保留关键字 - 您不能将其用作 output 中的列名。 (从技术上讲,你可以通过额外的工作,但最好相信你不能。)

with
  t as (
    select * 
    from   json_Table(
'{
 "Rownum": "1",
 "Name": "John",
 "AddressArray":["Address1", "Address2"],
 "TextObj":[{"mName" : "Carol","lName" : "Cena"},
            {"mName" : "Mark","lName" : "Karlo"}
           ]
}', 
           '$' columns (
                 rownr        number                     path '$.Rownum', 
                 name         varchar2(100)              path '$.Name', 
                 addressArray varchar2(4000) format json path '$.AddressArray',
                 nested path '$.TextObj[*]'
                   columns  (mName varchar2(100) path '$.mName',
                             lName varchar2(100) path '$.lName'
                            )
               )
           )
  )
select /*+ no_query_transformation */ rownr, name, mname, lname, address
from t
     outer apply
     json_table (t.addressArray, '$[*]'
                   columns (address varchar2(10) path '$')
     )
;

Output:

ROWNR NAME   MNAME  LNAME  ADDRESS   
----- ------ ------ ------ ----------
    1 John   Carol  Cena   Address1  
    1 John   Carol  Cena   Address2  
    1 John   Mark   Karlo  Address1  
    1 John   Mark   Karlo  Address2 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM