簡體   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