首页 > 解决方案 > 尝试在 oracle xquery 上使用 replace ((value),"\W","")

问题描述

有人可以解释为什么替换 \w (word-character) 有效而 \W (non-word-character) 无效。如何解决它。

create table test (xmldata) as
select xmltype('<workbook>
 <worksheet sheetName="asd-kasd" sheetId="1"/>
</workbook>') 
from dual;

update test
set XMLDATA=
           xmlquery(
             'copy $d := .
             modify (
                for $i in $d/workbook/worksheet/@sheetName
                return replace value of node $i with concat("1.\w:",replace(string($i/../@sheetName),"\w",""),"2. \W:",replace($i/../@sheetName,"\W",""))
            )
              return $d'
            passing test.XMLDATA
            returning content
         );

ORA-19112: error raised during evaluation: 
XVM-01126: [FORX0003] Regular expression matches zero-length string

小提琴: https ://dbfiddle.uk/?rdbms=oracle_18&fiddle=ede05cbbe55f36074c36457e9491fc11

错误:

ORA-19112: error raised during evaluation: 
XVM-01126: [FORX0003] Regular expression matches zero-length string

使用 \W 后

标签: oraclexquery

解决方案


这似乎是 Oracle 实现标准 XQueryfn:replace()函数中的一个错误。在我测试的每个字符串上,使用元字符\W都会导致失败。fn:replace我建议向 Oracle Support 提出服务请求来报告它。

您可以使用应该可以正常处理的非 Oracle XQuery 测试器(例如此处)进行验证。replace()\W

奇怪的是,已弃用的ora:replace()函数确实可以正常工作。因此,您可以将其用作解决方法,直到 Oracle 修补该错误。但请注意,此函数是非标准的——例如,它支持[[:alnum:]]XQuery 标准不支持的 POSIX 样式元字符(例如 )。

我简化了您的查询以提供一个更简单的可验证示例,并且可以在 Oracle 12.2.0.1 上重现该问题。注释掉“fn”列以获得正确的结果。

select 
    regexp_replace('asd-kasd','\W','') as rr, -- normal regexp engine works fine
    -- \W fails, with any string
    xmlquery('fn:replace("asd-kasd","\W","")' returning content) as fn,
    -- deprecated ora:replace works fine
    xmlquery('ora:replace("asd-kasd","\W","")' returning content) as ora
from dual

小提琴


推荐阅读