首页 > 解决方案 > 将动态 JSON 解析为 Oracle 表

问题描述

我有一个带有这样的表的 Oracle 12c 数据库

    (
      MSISDN        VARCHAR2(15 BYTE),
      DOCUMENT      VARCHAR2(15 BYTE),
      LOAD_DATE     DATE,
      LIST_NAME     VARCHAR2(40 BYTE),
      ATRIB         VARCHAR2(40 BYTE),
      VALUE         VARCHAR2(200 BYTE)
    )

另一方面,我有这个包含该表数据的 JSON

{
   "DigitalClient":{
      "documentNumber":"99999999-R",
      "documentType":"PASSPORT",
      "lastLineDate":123213213213,
      "lastClientDate":123213213213,
      "segment":"EMPRESA"
   },
   "ADSL":{
      "idOrder":216668542,
      "status":"COMPLETED",
      "orderType":"STANDARD",
      "documentNumber":"161893223R",
      "technologyAccess":"FTTVULA",
      "dUserLastModifiedDate":1571329345000,
      "type":"PERSON"
   }
}

我们的想法是以这种方式解析表中的这些信息:

MSISDN       DOCUMENT       LOAD_DATE       LIST_NAME      ATRIB           VALUE
------       ---------      -----------     ------------   --------        -----
911231231    6745671A       05/12/19        DigitalClient  documentNumber  99999999R
911231231    6745671A       05/12/19        DigitalClient  documentType    PASSPORT
911231231    6745671A       05/12/19        ADSL           idOrder         216668542
...

前三个字段是在 JSON 文件之外获取的,JSON 文件相关字段是后三个。可以看到,字段 LIST_NAME 填充的是一级名称,而 ATRIB 和 VALUE 字段填充的是二级名称和值

现在,最困难的部分。JSON 结构每天都在变化。我不知道 JSON 文件包含什么,既不知道一级或二级字段名称,也不知道有多少结构。我唯一知道的是该文件只有两层深:第一层是属性列表的名称,第二层是每个列表的属性及其值。

任何人都知道实现这一目标的好方法吗?我尝试使用此处显示的解决方案,但不是我想要的,因为我必须在第一列中使用 SUBSTR 提取 LIST_NAME 和 ATRIB 信息,并且对于加载大量记录不是很有效。

提前致谢!

标签: jsonoracleplsqloracle12c

解决方案


如果您使用的是 12.2,则可以使用JSON 数据指南为您创建视图:

create table t (
  jdata varchar2(1000)
    check ( jdata is json )
);

create search index ji 
  on t ( jdata )
  for json
  parameters ( 'sync (on commit)' );

insert into t values ('{
   "DigitalClient":{
      "documentNumber":"99999999-R",
      "documentType":"PASSPORT",
      "lastLineDate":123213213213,
      "lastClientDate":123213213213,
      "segment":"EMPRESA"
   },
   "ADSL":{
      "idOrder":216668542,
      "status":"COMPLETED",
      "orderType":"STANDARD",
      "documentNumber":"161893223R",
      "technologyAccess":"FTTVULA",
      "dUserLastModifiedDate":1571329345000,
      "type":"PERSON"
   }
}');

commit;

begin
  dbms_json.create_view_on_path ( 
    'vw', 't', 'jdata', '$'
  ); 
end;
/

select * from vw;

JDATA$type   JDATA$status   JDATA$idOrder   JDATA$orderType   JDATA$documentNumber   JDATA$technologyAccess   JDATA$dUserLastModifiedDate   JDATA$segment   JDATA$documentType   JDATA$lastLineDate   JDATA$documentNumber_1   JDATA$lastClientDate   
PERSON        COMPLETED              216668542 STANDARD           161893223R              FTTVULA                                    1571329345000 EMPRESA          PASSPORT                       123213213213 99999999-R                           123213213213 

请注意,您需要is json约束和搜索索引才能工作。

如果 JSON 包含一个数组,您将在输出中的每个元素中获得一行。

例如:

insert into t values ( '{ "aDifferent" : ["array", "of", "stuff"] }' );
commit;

begin
  dbms_json.create_view_on_path ( 
    'vw', 't', 'jdata', '$'
  ); 
end;
/

select * from vw;

JDATA$type JDATA$status  JDATA$idOrder JDATA$orderType JDATA$documentNumber JDATA$technologyAccess  JDATA$dUserLastModifiedDate JDATA$segment JDATA$documentType JDATA$lastLineDate JDATA$documentNumber_1 JDATA$lastClientDate JDATA$string   
PERSON     COMPLETED         216668542 STANDARD        161893223R           FTTVULA                               1571329345000 EMPRESA       PASSPORT                 123213213213 99999999-R                     123213213213 <null>          
<null>     <null>               <null> <null>          <null>               <null>                                       <null> <null>        <null>                         <null> <null>                               <null> array           
<null>     <null>               <null> <null>          <null>               <null>                                       <null> <null>        <null>                         <null> <null>                               <null> of              
<null>     <null>               <null> <null>          <null>               <null>                                       <null> <null>        <null>                         <null> <null>                               <null> stuff           

如果 JSON 文档中的属性名称发生变化,那么您将不断在视图中获得新列。因此,您可能希望在创建它之前删除它。


推荐阅读