从 Oracle PL/SQL 中的表生成 json 文件
Posted
技术标签:
【中文标题】从 Oracle PL/SQL 中的表生成 json 文件【英文标题】:Generating json file from table in Oracle PL/SQL 【发布时间】:2020-08-22 12:16:07 【问题描述】:我在表格中有以下表格中的数据。
我想生成以下格式的数据。
"delete": [
"canonicalName": "TCS"
],
"update": [
"canonicalName": "Wipro tech"
"synonyms": [
"Wipro technology"
]
,
"canonicalName": "Infosys"
"synonyms": [
"Infosys tech"
]
]
"add": [
"canonicalName": "Apple Computers",
"synonyms": [
"Apple"
]
,
"canonicalName": "Google India",
"synonyms": ["Google"]
]
我可以使用一些库和 POJO 类在 java 中编写相同的代码。我可以在 Oracle PL/SQL 中创建任何可能性吗?早些时候我从 jdbc 读取数据并在 java 代码中创建这个文件。现在我必须将此代码保留为 pl/sql 过程的一部分。无论如何我可以生成上述格式的数据吗?
【问题讨论】:
你的 oracle 版本是什么?是 >=12.2 吗? 假设您还有一行,ORGNAME = 'Apple Computers',SYNONYMS = 'Apple Inc',OPERATION = 'add'。在这种情况下,所需的结构是什么? canonicalName = 'Apple Computers' 的两个不同元素是否会出现在“add”的数组中,每个元素都只有一个同义词?还是会将它们组合成一个具有 canonicalName = 'Apple Computers' 的元素,并将所有同义词收集到一个(可能的多元素)同义词数组中? @SayanMalakshinov 是的,它是 18c 规范名称是唯一的 【参考方案1】:如果您的数据库版本是12cR2+
,那么您可以将json_objectagg()
、json_object()
和json_array()
函数一起用作
SELECT json_query(
json_objectagg
( operation VALUE
json_array(json_object('canonicalName' VALUE orgname,
'synonyms' VALUE json_array(synonyms) ) ) ),
'$' returning VARCHAR2(4000) pretty )
AS "Result JSON"
FROM tab
不要忘记添加json_query( ... , '$' returning VARCHAR2(4000) pretty )
包裹整个表达式以获得漂亮的外观。
Demo
【讨论】:
如果我的假设(如下所述)是正确的,那么您的解决方案并不完全正确。即:假设在输入中,对于相同的“操作”和相同的“组织名称”,有几个同义词。然后我假设(OP 需要澄清)"synonyms"
属性必须是单个数组,聚合该组织的所有同义词。在您的解决方案中,相同的orgname
将在同一个“操作”下多次出现。【参考方案2】:
在您的输出中,当一个组织只有一个规范名称(没有同义词)时,您会显示只有一个属性的对应对象,即规范名称。如果您允许 "synonyms"
属性在所有情况下都存在会更容易 - 相应的数组可以为空 - 但这不是您在所需输出中显示的内容。
如果您允许空数组作为 "synonyms"
的值,那么 Barbaros Ozhan 已经提供了解决方案。 编辑 经检查,这可能并不完全正确;该解决方案不会将单个组织的同义词聚合到单个数组中(具有两个或多个同义词),而是将它们显示为不同的对象。请参阅下面我添加到我的答案中的示例数据。 结束编辑
此处进行大量编辑我正在添加示例数据以进行测试。我假设如果一个组织有两个或多个同义词(在同一个操作下),那应该导致操作数组的单个成员(规范名称只出现一次,具有两个或多个同义词的数组)。
我也修改了我的解决方案 - 找到了一种更简单的方法。通过点击答案下方的“已编辑”链接,可以看到对解决方案的更改。
测试数据:
drop table t purge;
create table t (orgname, synonyms, operation) as
select 'Apple Computers', 'Apple' , 'add' from dual union all
select 'Apple Computers', 'Apple Inc' , 'add' from dual union all
select 'Google India' , 'Google' , 'add' from dual union all
select 'Wipro Tech' , 'Wipro Technology', 'update' from dual union all
select 'Infosys' , 'Infosys Tech' , 'update' from dual union all
select 'TCS' , null , 'delete' from dual union all
select 'IBM' , null , 'delete' from dual union all
select 'IBM' , 'IBM Corporation' , 'delete' from dual union all
select 'IBM' , 'IBM Corporation' , 'add' from dual
;
查询:
with
prep (operation, orgname, fragment) as (
select operation, orgname,
json_object( key 'canonicalName' value orgname,
key 'synonyms'
value nullif(json_arrayagg(synonyms order by synonyms), '[]')
FORMAT JSON ABSENT ON NULL
)
from t
group by orgname, operation
)
select json_objectagg( key operation
value json_arrayagg(fragment order by orgname)
) as json_str
from prep
group by operation
;
输出(漂亮的打印):
"add" :
[
"canonicalName" : "Apple Computers",
"synonyms" :
[
"Apple",
"Apple Inc"
]
,
"canonicalName" : "Google India",
"synonyms" :
[
"Google"
]
,
"canonicalName" : "IBM",
"synonyms" :
[
"IBM Corporation"
]
],
"delete" :
[
"canonicalName" : "IBM",
"synonyms" :
[
"IBM Corporation"
]
,
"canonicalName" : "TCS"
],
"update" :
[
"canonicalName" : "Infosys",
"synonyms" :
[
"Infosys Tech"
]
,
"canonicalName" : "Wipro Tech",
"synonyms" :
[
"Wipro Technology"
]
]
【讨论】:
首先非常感谢@mathguy 提供了这么棒的答案。情况是可以有多个同义词,如果同义词为空,我们可以删除同义词选项卡, 嗨@Mathguy 我已经稍微扩展了我的要求。你的解决方案对我来说是完美的。你能帮我做些改变吗? ***.com/questions/63541003/…以上是关于从 Oracle PL/SQL 中的表生成 json 文件的主要内容,如果未能解决你的问题,请参考以下文章