【问题标题】:Unable to fetch data using extractvalue function无法使用 extractvalue 函数获取数据
【发布时间】:2018-11-23 21:19:36
【问题描述】:

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

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 从“Plan Payment”替换为“Pre Plan Payment”。

【问题讨论】:

  • 你的记录节点没有内容,只有属性;那么您希望看到什么输出?

标签: sql xml oracle xpath


【解决方案1】:

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

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

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

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

但是,the extractvalue() function 早已被弃用,所以无论如何你都不应该使用它。

您可以使用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"/>

The updatexml() function 也已弃用。您也可以使用 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>

如果您想更新表中的值,您可以使用相同的查询作为更新语句的一部分,过滤匹配的行。 Read more.

【讨论】:

  • 谢谢@Alex。我可以通过您给定的语法使用 updatexml 进行更新。虽然我不能使用 XMLQuery 它仍然返回 null
猜你喜欢
  • 2015-03-05
  • 1970-01-01
  • 2017-08-02
  • 2022-01-01
  • 1970-01-01
  • 2018-01-25
  • 2012-10-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多