![](/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.