0

我在 Oracle DB 中有一个包含 XML 类型列的表。我正在尝试使用该表上的extractvalueandupdatexml函数。

XML

<?xml version = '1.0' encoding = 'UTF-8'?>
<custominfo>
   <singlerecord  ZIP="51100"/>
   <multiplerecord type="ONE_TIME_CHARGES_LIST">
      <record DESCRIPTION="Device Payment" RATE="1000000" TAX="0"/>
      <record DESCRIPTION="Plan Payment" RATE="480000" TAX="0"/>
      <record DESCRIPTION="Deposit" RATE="1000000" TAX="0"/>
   </multiplerecord>
</custominfo> 

询问

select EXTRACTVALUE(XMLCONTENT,'//record[@DESCRIPTION="Plan Payment"]') from TABLE_XML  X;

谁能建议我在这里做错了什么?

整理出摘录后,我想将DESCRIPTION“计划付款”替换为“计划前付款”。

4

1 回答 1

2

您正在做的是工作 - 它为您提供具有该属性值的记录节点的文本值。但是那个节点是空的:

<record DESCRIPTION="Plan Payment" RATE="480000" TAX="0"/>

具有三个属性,但节点本身没有内容 - 它是一个空标签。因此,您的查询返回 null,这是正确的。如果您想查看是否找到了该节点,则可以改为获取属性值:

select EXTRACTVALUE(XMLCONTENT,'//record[@DESCRIPTION="Plan Payment"]/@DESCRIPTION')
from TABLE_XML  X;

但是,extractvalue()功能早已被弃用,因此无论如何您都不应该真正使用它。

您可以使用XMLQuery查看整个匹配record节点;由于节点没有内容,因此获取其内容没有多大意义,就像您当前的查询一样:

select XMLQuery('$x//record[@DESCRIPTION="Plan Payment"]'
    passing xmlcontent as "x"
    returning content
  ) as result
from table_xml;

RESULT                                                                          
--------------------------------------------------------------------------------
<record DESCRIPTION="Plan Payment" RATE="480000" TAX="0"/>

updatexml()功能也已弃用。您也可以使用 XMLQuery 来修改属性名称:

select XMLQuery('copy $i := $x modify
    (for $j in $i//record[@DESCRIPTION="Plan Payment"]/@DESCRIPTION
      return replace value of node $j with $r)
    return $i'
    passing xmlcontent as "x", 'Pre Plan Payment' as "r"
    returning content
  ) as result
from table_xml;

为您的示例 XML 文档使用 CTE,并将其包装在 XMLSerialize 调用中以保留格式以提高可读性:

with table_xml (xmlcontent) as (
  select xmltype(q'[<?xml version = '1.0' encoding = 'UTF-8'?>
<custominfo>
   <singlerecord  ZIP="51100"/>
   <multiplerecord type="ONE_TIME_CHARGES_LIST">
      <record DESCRIPTION="Device Payment" RATE="1000000" TAX="0"/>
      <record DESCRIPTION="Plan Payment" RATE="480000" TAX="0"/>
      <record DESCRIPTION="Deposit" RATE="1000000" TAX="0"/>
   </multiplerecord>
</custominfo>]'
  ) from dual
)
select XMLSerialize(
    document
    XMLQuery('copy $i := $x modify
      (for $j in $i//record[@DESCRIPTION="Plan Payment"]/@DESCRIPTION
        return replace value of node $j with $r)
      return $i'
      passing xmlcontent as "x", 'Pre Plan Payment' as "r"
      returning content
    )
    indent
  ) as result
from table_xml;

RESULT                                                                          
--------------------------------------------------------------------------------
<?xml version="1.0" encoding="UTF-8"?>
<custominfo>
  <singlerecord ZIP="51100"/>
  <multiplerecord type="ONE_TIME_CHARGES_LIST">
    <record DESCRIPTION="Device Payment" RATE="1000000" TAX="0"/>
    <record DESCRIPTION="Pre Plan Payment" RATE="480000" TAX="0"/>
    <record DESCRIPTION="Deposit" RATE="1000000" TAX="0"/>
  </multiplerecord>
</custominfo>

如果要更新表中的值,可以使用相同的查询作为更新语句的一部分,对匹配的行进行过滤。阅读更多

于 2018-06-14T08:29:58.467 回答