在 Oracle SQL 中用 NULL 值替换特定的 XML 标签

Replace Particular XML tag with NULL value in Oracle SQL

我在 DUMMY table 中有列作为 VALUE,类型为 XMLTYPE。 它包含:

  <?xml version="1.0"?>
  <ROWSET>
  <Value>
    <Data>802
     </Data>
  </Value>
  <Value>
    <Data>902
      </Data>
    </Value>
  </ROWSET>

我需要用 NULL 替换 802 值标记。 输出应该是:

  <?xml version="1.0"?>
   <ROWSET>
  <Value>
    <Data>902
     </Data>
  </Value>
  </ROWSET>

802 值标签应该用 NULL 删除。

我试过 UpdateXML():

  update Dummy set VALUE=updatexml(VALUE,'ROWSET/Value/Data/text()','');

但它只会将 802 值更新为 null。

第二种方法: 更新虚拟集 Value=updatexml(Value,'ROWSET','');

但它会删除 ROWSET tag.Then 中的所有内容,它只会包含:

<?xml version="1.0"?>
<ROWSET/>

我也试过 Replace()。

     update Dummy set emps=replace('
      <Value><Data>802
      </Data></Value>',null);

然后它将从 VALUE 列中删除其他值,并仅保留 replace() 中提到的标记。

在这个replace()之后,它包含:

  <Value><Data>802
  </Data></Value>

请给我建议。

你需要

  • deleteXml() 而不是 updateXml(),并且
  • 要删除的内容的正确 XPath。

让我们先测试一下我们的 XPath

with input$ as (
    select --+ no_merge
        xmltype(q'{<?xml version="1.0"?>
      <ROWSET>
      <Value>
        <Data>802
         </Data>
      </Value>
      <Value>
        <Data>902
          </Data>
        </Value>
      </ROWSET>}') as xx
    from dual
)
select
    xmlserialize(document X.xx indent) as original,
    xmlserialize(document
        deletexml(X.xx, '/ROWSET/Value[normalize-space(Data)="802"]')
        indent
    ) as with_802_removed
from input$ X;

...产量...

ORIGINAL               WITH_802_REMOVED
---------------------- ----------------------
<?xml version="1.0"?>  <?xml version="1.0"?>
<ROWSET>               <ROWSET>
  <Value>                <Value>
    <Data>802              <Data>902
         </Data>                 </Data>
  </Value>               </Value>
  <Value>              </ROWSET>
    <Data>902                                                                    
          </Data>                                                                
  </Value>                                                                       
</ROWSET>                                                                        

注意:这里使用xmlserialize()函数只是为了美观。

现在更新

update Dummy X
set X.value = deletexml(X.value, '/ROWSET/Value[normalize-space(Data)="802"]');

Oracle 12c 注释:使用 XQuery 应该有更优雅的解决方案,但我还不能完全掌握 XQuery 语言,因此我仅向您展示 deleteXml() 解决方案。