在 Oracle PL/SQL 中从 table 生成 json 文件
Generating json file from table in Oracle PL/SQL
我在 table 中有以下表格的数据。
我想生成以下格式的数据。
{
"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 class 在 java 中编写相同的内容。有没有可能我可以在 Oracle PL/SQL 中创建?早些时候我从 jdbc 读取数据并用 java 代码创建这个文件。现在我必须将此代码保留为 pl/sql 过程的一部分。无论如何我可以生成上述格式的数据吗?
如果您的数据库版本是 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 )
包裹整个表达式以获得漂亮的外观。
在您的输出中,当一个组织只有一个规范名称(没有同义词)时,您只显示一个 属性 规范名称的相应对象。如果您允许 "synonyms"
属性 在所有情况下都存在会更容易 - 相应的数组可以为空 - 但这不是您在所需输出中显示的内容。
如果您允许空数组作为 "synonyms"
的值,那么 Barbaros Ozhan 已经提供了解决方案。 编辑 经检查,这可能不完全正确;该解决方案不会将单个组织的同义词聚合到一个数组中(具有两个或更多同义词),而是将它们显示为不同的对象。请参阅下面我添加到答案中的示例数据。 结束编辑
此处进行大量编辑 我正在添加示例数据以进行测试。我假设如果一个组织有两个或更多同义词(在同一个操作下),那应该导致操作数组的单个成员(规范名称只出现一次,带有两个或更多同义词的数组)。
我也修改了我的解决方案 - 找到了更简单的方法。单击答案下方的“已编辑”link 可以看到对解决方案的更改。
测试数据:
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"
]
}
]
}
我在 table 中有以下表格的数据。
我想生成以下格式的数据。
{
"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 class 在 java 中编写相同的内容。有没有可能我可以在 Oracle PL/SQL 中创建?早些时候我从 jdbc 读取数据并用 java 代码创建这个文件。现在我必须将此代码保留为 pl/sql 过程的一部分。无论如何我可以生成上述格式的数据吗?
如果您的数据库版本是 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 )
包裹整个表达式以获得漂亮的外观。
在您的输出中,当一个组织只有一个规范名称(没有同义词)时,您只显示一个 属性 规范名称的相应对象。如果您允许 "synonyms"
属性 在所有情况下都存在会更容易 - 相应的数组可以为空 - 但这不是您在所需输出中显示的内容。
如果您允许空数组作为 "synonyms"
的值,那么 Barbaros Ozhan 已经提供了解决方案。 编辑 经检查,这可能不完全正确;该解决方案不会将单个组织的同义词聚合到一个数组中(具有两个或更多同义词),而是将它们显示为不同的对象。请参阅下面我添加到答案中的示例数据。 结束编辑
此处进行大量编辑 我正在添加示例数据以进行测试。我假设如果一个组织有两个或更多同义词(在同一个操作下),那应该导致操作数组的单个成员(规范名称只出现一次,带有两个或更多同义词的数组)。
我也修改了我的解决方案 - 找到了更简单的方法。单击答案下方的“已编辑”link 可以看到对解决方案的更改。
测试数据:
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"
]
}
]
}