首页 > 解决方案 > 如何重构通过nvl2向json添加属性以避免重复?

问题描述

我们正在创建标签名称和相应标签值的 json:

[
  "name": "bob",
  "surname": "dylan",
  ...
]

这是通过首先创建一个主选择来完成的,然后通过包含数十个nvl2函数来调用适当的程序来获取每个标签的值:

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(...)...

(1) 检查是否存在任何值(例如,对于标签“meetingParticipants”,可能不存在参与者)
(2) 如果存在,则调用实际获取该值并将其形成必要的 nclob 的过程,并添加这个和tag 到 json (3) 如果它不存在,然后检查是否应该在 json 中添加空标签,然后添加一个空标签或不添加一个

可以重构它以便ExecuteSelectToCheckIfValueExists()根本不调用它吗?我们可以检查然后,如果这个函数没有找到结果,v_remove_empty_tags返回或。但是如何从该结果中形成适当的 json 呢?ExecuteAVerySimilarSelectToGetValue()-1null

标签: sqljsonoracle

解决方案


我不知道你的函数u_json_pck和类型nclob_tt到底是做什么的,但为什么不使用内置的 JSON 语法来做到这一点,例如:

select json_object
         ( 'myobject' value json_arrayagg
                            ( json_object
                                ( 'tag_name1'  value value1
                                , 'tag_name2'  value value2
                                , 'tag_name3'  value value3
                                absent on null
                                ) 
                              returning clob
                             )
         ) json_data
  from
  ( select null value1, 'BBB' value2, 'CCC' value3 from dual
    union all
    select null value1, 'BBB' value2, null value3 from dual
    union all
    select 123 value1, null value2, 'DDD' value3 from dual
    union all
    select 456 value1, 'EEE' value2, null value3 from dual
  );

返回:

{
  "myobject": [
    {
      "tag_name2": "BBB",
      "tag_name3": "CCC"
    },
    {
      "tag_name2": "BBB"
    },
    {
      "tag_name1": 123,
      "tag_name3": "DDD"
    },
    {
      "tag_name1": 456,
      "tag_name2": "EEE"
    }
  ]
}

您只需要根据 - 的值进行更改absent on null,因此要么为每个单独的语句,要么动态构造 SQL 来指定它。null on nullv_remove_empty_tagsselect


推荐阅读