如何重构通过nvl2为JSON新增属性的逻辑以消除重复查询?
]
当前实现方式为先创建一个主select,随后在其中写入数十个`nvl2`函数调用对应逻辑获取每个标签的取值: ```sql select u_json_pck.JsonPropertyObject(null, nclob_tt( nvl2(ExecuteSelectToCheckIfValueExists(), U_JSON_PCK.JsonProperty('TAG_NAME', ExecuteAVerySimilarSelectToGetValue()), decode(v_remove_empty_tags, 1, U_JSON_PCK.JsonProperty('TAG_NAME', ''), null)), nvl2(......), nvl2(...)...
现有逻辑如下:
- 先调用
ExecuteSelectToCheckIfValueExists()检查对应标签值是否存在,例如"meetingParticipants"标签可能没有参会人数据 - 若存在,调用实际获取值的逻辑将结果封装为所需的nclob格式,将该标签和值加入JSON
- 若不存在,检查
v_remove_empty_tags配置,判断是否需要添加空标签,对应添加空值或不添加该标签
我们希望可以去掉ExecuteSelectToCheckIfValueExists()的调用完成重构,考虑可以在ExecuteAVerySimilarSelectToGetValue()中判断v_remove_empty_tags配置,若查询无结果则返回-1或null,请问如何基于该返回值生成符合要求的JSON?
解决方案
方案1:最小改动复用现有逻辑(无需修改取值函数)
直接将nvl2的第一个判断参数替换为ExecuteAVerySimilarSelectToGetValue()的返回值即可,原有判断逻辑几乎不用调整,即可去掉重复的存在性检查查询:
select u_json_pck.JsonPropertyObject(null, nclob_tt( nvl2(ExecuteAVerySimilarSelectToGetValue('TAG_NAME'), U_JSON_PCK.JsonProperty('TAG_NAME', ExecuteAVerySimilarSelectToGetValue('TAG_NAME')), decode(v_remove_empty_tags, 1, U_JSON_PCK.JsonProperty('TAG_NAME', ''), null)), -- 其余标签都按上面的结构替换即可 ... ) )
逻辑说明:
- 若
ExecuteAVerySimilarSelectToGetValue()返回非空值,直接用该值生成标签属性,无需再做二次查询 - 若返回空值,走原有
decode逻辑,根据v_remove_empty_tags配置决定是生成空值标签还是忽略该标签
方案2:优化避免重复调用取值函数
如果不想每个标签调用两次ExecuteAVerySimilarSelectToGetValue(),可以提前缓存取值结果,PL/SQL场景下示例如下:
DECLARE -- 标签值缓存变量,可根据标签数量声明多个或者用关联数组存储 v_tag_meeting_val NCLOB; v_remove_empty_tags NUMBER := 1; -- 全局配置项 v_final_json NCLOB; BEGIN -- 每个标签仅调用一次取值函数 v_tag_meeting_val := ExecuteAVerySimilarSelectToGetValue('meetingParticipants'); SELECT u_json_pck.JsonPropertyObject(null, nclob_tt( nvl2(v_tag_meeting_val, U_JSON_PCK.JsonProperty('meetingParticipants', v_tag_meeting_val), decode(v_remove_empty_tags, 1, U_JSON_PCK.JsonProperty('meetingParticipants', ''), null)), ... ) ) INTO v_final_json FROM DUAL; -- 后续处理生成的JSON END; /
方案3:修改取值函数简化判断逻辑
如果可以调整ExecuteAVerySimilarSelectToGetValue()的实现,直接在函数内部集成v_remove_empty_tags的判断逻辑:
- 查询有结果时返回实际取值
- 查询无结果时,若
v_remove_empty_tags=1返回空字符串'',否则返回null
此时外层判断可以进一步简化为:
nvl2(v_tag_val, U_JSON_PCK.JsonProperty('TAG_NAME', v_tag_val), null)
内容的提问来源于stack exchange,提问作者vr552
相关产品推荐
相关产品推荐

