運行環境:SQLPLUS, SERVEROUTPUT已打開
我有一張用戶表,包含一個JSON列,裏面是他們的社交媒體資料:
create table qz_users (
id integer primary key
, username varchar2(10)
, profiles varchar2(4000) check (profiles is json)
)
/
insert into qz_users values (68, 'Benjamin', '[
{ "site" : "twitter" , "name" : "benjamin68" }
, { "site" : "facebook" , "name" : "benjyface" }
]')
/
insert into qz_users values (96, 'Barbara', '[
{ "site" : "twitter" , "name" : "barbiegirl" }
, { "site" : "instagram", "name" : "cutiebarb" }
, { "site" : "pinterest", "name" : "barb1996" }
]')
/
commit
/
我想要一個用戶列表,連接到他們的社交媒體資料,有兩個列包含着JSON列表中的site和name屬性的值,如下所示:
ID USERNAME SITE NAME
---------- ---------- ---------- ----------
68 Benjamin facebook benjyface
68 Benjamin twitter benjamin68
96 Barbara instagram cutiebarb
96 Barbara pinterest barb1996
96 Barbara twitter barbiegirl
哪些選項執行不出錯並且產生所示的輸出?
(A)
select u.id, u.username, p.site, p.name
from qz_users u
, json_table (
u.profiles, '$[*]'
columns (
site varchar2(10) path '$.site'
, name varchar2(10) path '$.name'
)
) p
order by u.id, p.site
/
(B)
select u.id, u.username, p.site, p.name
from qz_users u
, json_table (
u.profiles, '$[*]'
columns (
site varchar2(10)
, name varchar2(10)
)
) p
order by u.id, p.site
/
(C)
select u.id, u.username, p.site, p.name
from qz_users u
, json_table (
u.profiles
columns (
site varchar2(10)
, name varchar2(10)
)
) p
order by u.id, p.site
/
(D)
select u.id, u.username, p.site, p.name
from qz_users u
, json_table (
u.profiles
columns (
site varchar2(10) path '$[*].site'
, name varchar2(10) path '$[*].name'
)
) p
order by u.id, p.site
/
(E)
select u.id, u.username, p.site, p.name
from qz_users u
, json_table (
u.profiles
columns (
site varchar2(10)
, name varchar2(10)
)
) p
order by u.id, p.site
/
(F)
select u.id, u.username, p.site, p.name
from qz_users u
, json_table (
u.profiles, '$[*]'
columns (
obj varchar2(4000) format json path '$'
)
) o
, json_table (
o.obj, '$'
columns (
site varchar2(10) path '$.site'
, name varchar2(10) path '$.name'
)
) p
order by u.id, p.site
/
(G)
select u.id, u.username, p.site, p.name
from qz_users u
, json_table (
u.profiles, '$[*]'
columns (
obj varchar2(4000) format json path '$'
)
) o
, json_table (
o.obj
columns (
site varchar2(10)
, name varchar2(10)
)
) p
order by u.id, p.site
/
(H)
with p_obj as (
select u.id, u.username, o.obj
from qz_users u
, json_table (
u.profiles, '$[*]'
columns (
obj varchar2(4000) format json path '$'
)
) o
where rownum > 0
)
select p_obj.id, p_obj.username, p.site, p.name
from p_obj
, json_table (
p_obj.obj, '$'
columns (
site varchar2(10) path '$.site'
, name varchar2(10) path '$.name'
)
) p
order by p_obj.id, p.site
/
(I)
with p_obj as (
select u.id, u.username, o.obj
from qz_users u
, json_table (
u.profiles, '$[*]'
columns (
obj varchar2(4000) format json path '$'
)
) o
where rownum > 0
)
select p_obj.id, p_obj.username, p.site, p.name
from p_obj
, json_table (
p_obj.obj
columns (
site varchar2(10)
, name varchar2(10)
)
) p
order by p_obj.id, p.site
/
答案ABHI
A: JSON_TABLE的普通用法,指定了“記錄”的路徑以及每條記錄中的列的路徑。
B: 在18C版本中,我們可以跳過制定的列路徑----於是路徑就缺省爲$.{列名}, 這意味着這個選項和前一選項是相同的。
C: 在18C版本中,你還可以跳過A選項中的“記錄”路徑,但是我們不能夠使用[*]這種風格的訪問路徑表達式來得到數組中的每個對象。這會報錯:
ORA-02000: missing COLUMNS keyword.
D: 如果我們完全跳過了[*], 那麼JSON_TABLE的“記錄”就變成了整個數組----因爲我們沒有指定“記錄”路徑,它缺省爲'$',那意味着我們得不到正確的行數,而列路徑不起作用,導致了NULL值,總而言之我夢得到這個錯誤的輸出:
ID USERNAME SITE NAME
---------- ---------- ---------- ----------
68 Benjamin
96 Barbara
E: 正如前一選項,JSON_TABLE的“記錄”是整個數組。此處我們只是沒有制定列路徑,所以它們缺省爲 $.site 和 $.name, 當這被應用於數組而不是數組中的對象,就導致了NULL值,所以我們得到了和前一選項相同的錯誤輸出。
F:
原則上,這看起來像一個冗長但有效的與選項A相同的寫法。但它不起作用,會報錯:
ORA-40556: unsupported chaining of JSON_TABLE
隨後的建議是使用NESTED PATH,但是如果我們嘗試就會得到另一個錯誤:
ORA-40561: invalid path in JSON_TABLE nested path clause.
問題是,選擇A做得很好,而這樣做是沒有意義的。
G: 原則上,這似乎比前一選項更有道理,因爲創建O.OBJ列應該允許我們完全跳過第二個JSON_TABLE調用中的JSON路徑說明。但不行的是,我們仍然會得到這個錯誤:
ORA-40556: unsupported chaining of JSON_TABLE.
H: 如果我們利用有個經典技巧,通過使用WHERE ROWNUM > 0把第一個JSON_TABLE的輸出進行“物化”,我們就可以避免前兩個選項的unsupported chaining錯誤。這是可行的,只是多了很多不必要的工作。
I: 利用這個技巧也允許我們跳過第二個JSON_TABLE中的路徑表達式並且使得缺省值和前一選項完全一樣。
其他DEMO處理展示:
--從JSONArray中取數據
SELECT jt.*
FROM JSON_TABLE('[
{
"device_type_id": 1,
"amount": 120,
"remarks": ""
},
{
"device_type_id": 2,
"amount": 122,
"remarks": ""
},
{
"device_type_id": 3,
"amount": 123,
"remarks": "11111111111"
}
]','$'COLUMNS(NESTED PATH '$[*]' COLUMNS (device_type_id VARCHAR2(32) PATH '$.device_type_id',amount VARCHAR2(32) PATH '$.amount',remarks VARCHAR2(32) PATH '$.remarks')))
AS jt;
--從JSONObject對象中取數據
SELECT jt.*
FROM JSON_TABLE('{
"detailed": [
{
"device_type_id": 1,
"amount": 120,
"remarks": ""
},
{
"device_type_id": 2,
"amount": 122,
"remarks": ""
}
]
}
','$'
COLUMNS
(NESTED PATH '$.detailed[*]' COLUMNS (device_type_id VARCHAR2(32) PATH '$.device_type_id',amount VARCHAR2(32) PATH '$.amount',remarks VARCHAR2(32) PATH '$.remarks')))
AS jt;
SELECT *
FROM JSON_TABLE('{
"device_type_id": "1",
"amount": "120",
"remarks": ""
}
',
'$' COLUMNS(outer_value_0 NUMBER PATH '$.device_type_id',
outer_value_1 NUMBER PATH '$.amount'));
--從三層嵌套的JSONObject對象中取數據
SELECT jt.*
FROM JSON_TABLE('{
"certificate": "14531209693428a799591c0248bb95c3",
"rows": [
{
"odo_id": "0",
"odo_no": "ZC-FY-20170217001",
"stamp": "2017-02-24",
"order_no": "ZC-DD-20170210001",
"partners_id": "213",
"shipping_address": "深圳市福田區科技園南區T2-B棟601",
"contacts": "李魁",
"tel": "13510141822",
"self_mention": "0",
"detailed": [
{
"device_type_id": "1",
"amount": "121",
"remarks": ""
},{
"device_type_id": "2",
"amount": "122",
"remarks": ""
}
]
},{
"odo_id": "0",
"odo_no": "ZC-FY-20170217002",
"stamp": "2017-02-24",
"order_no": "ZC-DD-20170210001",
"partners_id": "213",
"shipping_address": "深圳市福田區科技園南區T2-B棟601",
"contacts": "李魁",
"tel": "13510141822",
"self_mention": "0",
"detailed": [
{
"device_type_id": "3",
"amount": "123",
"remarks": ""
},{
"device_type_id": "4",
"amount": "124",
"remarks": ""
}
]
}
]
}
', '$'
COLUMNS
(requestor VARCHAR2(32) PATH '$.certificate',NESTED PATH '$.rows[*]' COLUMNS (odo_no VARCHAR2(32) PATH '$.odo_no',NESTED PATH '$.detailed[*]' COLUMNS (phone_type VARCHAR2(32) PATH '$.device_type_id', phone_num VARCHAR2(20) PATH '$.amount'))))
AS jt;
原文鏈接:http://www.itpub.net/thread-2109001-1-1.html (newkid)
https://blog.csdn.net/e_wsq/article/details/60150077
【侵權刪】