Oracle提取重复XML标签值遇ORA-19025错误的技术求助
解决Oracle中extractValue触发ORA-19025错误并提取重复XML节点值
错误原因
ORA-19025错误的核心原因是extractValue函数只能返回单个XML节点的值,而你的XML结构中存在两个<Attribute Kind="ContractRid">节点,直接调用extractValue会因为匹配到多个节点触发报错。同时你现有语句的XPath写法逻辑有误([1][@Kind=...]是先取第一个Attribute再过滤类型,而非先过滤再取第一个),且存在命名空间重复定义的问题。
解决方案
Oracle从12c开始推荐使用XMLTable替代extractValue来处理多节点XML解析,以下是两种常用场景的实现:
1. 提取所有ContractRid值(每行一个)
通过XMLTable将XML中的多个ContractRid节点拆分为关系型数据行:
SELECT t.id, -- 替换为你的表主键或标识字段 x.contract_rid FROM TRAN t, XMLTable( NAMESPACES( 'http://schemas.tranzaxis.com/tran.xsd' AS "tran", DEFAULT 'http://schemas.tranzaxis.com/tran-common.xsd' ), '/tran:Response/tran:CustInfo/Item/Attribute[@Kind="ContractRid"]' PASSING CASE WHEN t.RESPONSESTR IS NOT NULL THEN XMLType(t.RESPONSESTR) ELSE XMLType(t.RESPONSELOB) END COLUMNS contract_rid VARCHAR2(100) PATH './StrVal' ) x;
- 命名空间说明:默认命名空间对应XML中的
xmlns="http://schemas.tranzaxis.com/tran-common.xsd",tran命名空间对应xmlns:tran="http://schemas.tranzaxis.com/tran.xsd"; - XPath路径精准定位到所有ContractRid节点,避免全局搜索(
//)的性能问题; ./StrVal自动匹配带/不带tran1前缀的节点(因为tran1的命名空间与默认命名空间一致)。
2. 将所有ContractRid合并为单个字符串
如果需要把多个ContractRid值合并成逗号分隔的字符串,使用LISTAGG聚合函数:
SELECT t.id, LISTAGG(x.contract_rid, ', ') WITHIN GROUP (ORDER BY x.contract_rid) AS contract_rids FROM TRAN t, XMLTable( NAMESPACES( 'http://schemas.tranzaxis.com/tran.xsd' AS "tran", DEFAULT 'http://schemas.tranzaxis.com/tran-common.xsd' ), '/tran:Response/tran:CustInfo/Item/Attribute[@Kind="ContractRid"]' PASSING CASE WHEN t.RESPONSESTR IS NOT NULL THEN XMLType(t.RESPONSESTR) ELSE XMLType(t.RESPONSELOB) END COLUMNS contract_rid VARCHAR2(100) PATH './StrVal' ) x GROUP BY t.id;
关于extractValue的替代说明
extractValue已被Oracle标记为废弃函数,官方建议使用XMLTable或XMLQuery来处理XML数据,这两种方式更灵活,支持多节点解析,避免单节点限制的报错。
内容的提问来源于stack exchange,提问作者Chandara MK
相关产品推荐
相关产品推荐

