我在Oracle DB中有一个包含XML Type列的表。我正在尝试使用该表上的extractvalue
和updatexml
函数。
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;
有人能说出我在这里做错了什么吗?
在整理提取后,我想要替换{&#34;计划付款&#34;中的DESCRIPTION
。到&#34;预先计划付款&#34;。
答案 0 :(得分:2)
您正在做的是工作 - 它为您提供具有该属性值的记录节点的文本值。但该节点为空:
<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;
将CTE用于示例XML文档,并将其包装在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