xml - PL/SQL 中的 XMLPATCH?
问题描述
我需要删除 XML 的某些部分(来自 DBMS_METADATA 的表定义)。找到 XMLPATCH 并使其适用于非常小的示例 XML。但我面临两个问题:一大一小。
- 最大的问题是下面的查询填满了所有实例的 PGA (PGA_TARGET=8GB),如果我在带有表定义的真实 25KB XML 上使用它。
- 小问题是我在 PL/SQL 中使用它,所以原生 PL/SQL 会比 SELECT FROM DUAL 更好;
有谁知道如何优化以下内容以正确删除 /ROWSET[1]/ROW[1]/TABLE_T[1]/CON1_LIST[1] 并使用最少的内存?
有谁知道如何将以下内容重写为 PL/SQL 代码?
SELECT XMLPATCH ( XMLTYPE( '<?xml version="1.0"?>
<ROWSET><ROW><TABLE_T><VERS_MAJOR>2</VERS_MAJOR><MAXTRANS>0</MAXTRANS>
<CON1_LIST><CON1_LIST_ITEM><OWNER_NUM>115</OWNER_NUM></CON1_LIST_ITEM></CON1_LIST>
<BHIBOUNDVAL empty="blob"/><PHYPART_NUM>10</PHYPART_NUM></TABLE_T></ROW></ROWSET>')
, XMLTYPE( '<?xml version="1.0"?>
<xd:xdiff xsi:schemaLocation="http://xmlns.oracle.com/xdb/xdiff.xsd
http://xmlns.oracle.com/xdb/xdiff.xsd"
xmlns:xd="http://xmlns.oracle.com/xdb/xdiff.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<?oracle-xmldiff operations-in-docorder="true" output-model="snapshot" diff-algorithm="global"?>
<xd:delete-node
xd:node-type="element"
xd:xpath="/ROWSET[1]/ROW[1]/TABLE_T[1]/CON1_LIST[1]"/>
</xd:xdiff>')
)
FROM DUAL;
```
解决方案
这个应该解决更大的问题,也应该更快:
select
XMLQuery('copy $i := $p modify
delete nodes $i/ROWSET[1]/ROW[1]/TABLE_T[1]/CON1_LIST[1]
return $i'
PASSING XMLTYPE( '<?xml version="1.0"?>
<ROWSET>
<ROW>
<TABLE_T>
<VERS_MAJOR>2</VERS_MAJOR>
<MAXTRANS>0</MAXTRANS>
<CON1_LIST>
<CON1_LIST_ITEM>
<OWNER_NUM>115</OWNER_NUM>
</CON1_LIST_ITEM>
</CON1_LIST>
<BHIBOUNDVAL empty="blob"/>
<PHYPART_NUM>10</PHYPART_NUM>
</TABLE_T>
</ROW>
</ROWSET>') AS "p"
RETURNING CONTENT
) xres
from dual;
不幸的是,我们仍然在 PL/SQL 中使用 SQL 来更新它:
declare
x xmltype:= XMLTYPE( '<?xml version="1.0"?>
<ROWSET><ROW><TABLE_T><VERS_MAJOR>2</VERS_MAJOR><MAXTRANS>0</MAXTRANS>
<CON1_LIST><CON1_LIST_ITEM><OWNER_NUM>115</OWNER_NUM></CON1_LIST_ITEM></CON1_LIST>
<BHIBOUNDVAL empty="blob"/><PHYPART_NUM>10</PHYPART_NUM></TABLE_T></ROW></ROWSET>');
res xmltype;
g_doc dbms_xmldom.DOMDocument; -- basic DOM-document
g_node dbms_xmldom.DOMNode;
begin
select
XMLQuery('copy $i := $p modify
delete nodes $i/ROWSET[1]/ROW[1]/TABLE_T[1]/CON1_LIST[1]
return $i'
PASSING x AS "p"
RETURNING CONTENT
)
into res
from dual;
dbms_output.put_line(res.getclobval());
end;
/
推荐阅读
- r - R中的Coeftest函数--输出中未报告变量
- unity3d - 将相机附加到与脚本相同的对象
- reactjs - 风格反应选择与阿芙罗狄蒂
- regex - 正则表达式以防止某些电话区号
- android - 连接 WiFi 时如何使用移动数据服务?
- python-3.x - 将通过html表单发送的xlsx转换为python中的csv/tsv
- outlook - 使用 MAPI 发送到 Outlook 2013 有什么特别之处吗?
- python - 将 Django 表单数据保存到用户
- r - 当 barplot 正确绘制所有内容时,ggplot 将所有数据绘制为单列
- c++ - scoped_lock 可以在读取模式下锁定 shared_mutex 吗?