一, 问题描述
最近, 用户抱怨 Oracle 12c 的某个查询结果出现了有重复记录的情况. 经调查分析, 查询 sql 涉及到 json_value 函数, 可简化为:
- select ID, json_value(json_field, '$.Code'), json_value(json_field, '$.Time')
- from json_table where ID=390;
在不同的测试库中, 有时结果为一条记录 (正确), 有时为二条记录 (错误).
再进一步分析, 发现出现改问题的记录, json_field 的内容均为 null.
二, 疑似 bug 的证据
在网上没有搜索到类似情况, 但依然认为其为疑似 bug, 证据为:
1 当 sql 只使用一个 json_value 函数时, 查询结果始终正确:
- select ID, json_value(json_field, '$.Code') from json_table where ID=390;
- select ID, json_value(json_field, '$.Time') from json_table where ID=390;
两条语句均只返回一条记录.
2 使用 count(*) 时, 查询结果始终正确:
- create or replace view json_view as
- select ID, json_value(json_field, '$.Code'), json_value(json_field, '$.Time') from json_table ;
select * from json_view; -- 结果为 2 条记录
select count(*) from json_view; -- 结果为 1
三, 解决办法
猜测是 json_value 函数在解析 null 时出现了偏差, 那么把 null 转换为最简单的有效 JSON 即可:
- select ID, json_value(nvl(json_field, '{}'), '$.Code'), json_value(nvl(json_field, '{}'), '$.Time')
- from json_table where ID=390;
-- 结果始终是一条记录
PS:
如果 sql 中涉及多个空的 JSON 字段, 那么可能出现更多的重复记录.
原始数据涉及客户机密, 只好如此处理.
来源: http://www.linuxidc.com/Linux/2019-07/159603.htm