![](/img/trans.png)
[英]Nested json data not captured by JSON_TABLE in oracle sql
[英]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 上验证)。
您似乎想要数组值的交叉连接(按rownum
和name
分组)。 这不是标准的 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.