json - 将动态 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 信息,并且对于加载大量记录不是很有效。
提前致谢!
解决方案
如果您使用的是 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 文档中的属性名称发生变化,那么您将不断在视图中获得新列。因此,您可能希望在创建它之前删除它。
推荐阅读
- javascript - 散列密码不适用于我
- python - 找不到路径目录
- laravel - 在 Laravel 的 DataTable 中制作“导出到 excel”按钮
- javascript - 在 JS 中使用 XLSX 将 JSON 转换为 Excel 工作表时如何跳过一些键值对
- sql-server-2014 - 如何修复命名管道提供程序,错误:40 - 无法打开与 SQL Server 的连接?
- git - Git分支和合并:致命:拒绝合并不相关的历史
- python - 在 BeautifulSoup 中如何用某些词分割汤?
- android - IFrameCallback 不起作用
- r - 如果页面加载时间过长,在 RSelenium 中自动刷新网页?
- bash - Bash 脚本未在 Jenkins 中以状态码 1 退出