Попытка использовать replace ((значение), "\ W", "") для oracle xquery - PullRequest
0 голосов
/ 27 марта 2020

Может ли кто-нибудь объяснить, почему \ w (слово-символ) работает, а \ W (не-символ-символ) - нет. Как ее решить.

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

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

Ошибка:

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

после использования \ W

1 Ответ

1 голос
/ 27 марта 2020

Это, похоже, ошибка в реализации Oracle стандартной функции XQuery fn:replace(). Использование метасимвола \W приводит к сбою fn:replace для каждой строки, которую я тестировал. Я бы предложил открыть запрос на обслуживание с помощью Oracle Support , чтобы сообщить об этом.

Вы можете проверить, используя не Oracle XQuery-тестер (например, здесь ) что replace() должен нормально обрабатывать \W.

Как ни странно, устаревшая функция ora: replace () работает правильно. Таким образом, вы можете использовать это в качестве обходного пути, пока Oracle не исправит ошибку. Но обратите внимание, что эта функция нестандартна - например, она поддерживает метасимволы POSIX-стиля (например, [[:alnum:]]), чего нет в стандарте XQuery.

Я упростил ваш запрос, чтобы дать более минимальный проверяемый пример, и может воспроизвести проблему на 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

Скрипка

...