PL/SQL Обноление CLOB содержащий XML

Столкнулась со следующий необходимостью обновить информацию в поле таблицы (формат CLOB) содержащее XML информацию с тэгами. Конкректно тэги в которых будет лежать информация не известны, например мне нужно обновить телефон клиента. Вопрос как сделать это наиболее быстро. На текущий момент сделала реализацию обновления следующим образом :

  1. завела переменную типа varchar(4000); -- переменная для входных данных
  2. считываю данные и записываю их в переменную select dbms_lob.substr(t.request, dbms_lob.getlength(t.request),1) as request into variable from logfiles t
  3. а дальше уже использую регулярные выражения ищу информацию с маской содержащий телефон REGEXP_SUBSTR()
  4. полученные данные передаю в clob, т.е. его обновлняю. Метод рабочий, но каждый раз clob записывать в varchar учитывая миллионы( как минимум) будет слишком затратно по ресурсам и долго. А выдержит ли БД такие нагрузки далеко не понятно (т.к. информации о технических сведениях вовсе не известны). Принимаются дельные советы и ссылки на статьи. Заранее спасибо.

Ответы (1 шт):

Автор решения: 0xdb

Если заранее известно, что и чем заменять, то стандартные функции по поиску и замене текста также реаботают для CLOB. Обычное обновление значения столбца будет достаточно:

create table t (id, doc) as
    select 1, to_clob ('<?xml version="1.0"?>
<contacts>
  <contact>
    <name>Ivan Ivanov</name>
    <phone>123-456-7890</phone>
  </contact>
  <contact>
    <name>Vasya Pupkin</name>
    <mobile>+7(923)-456-7891</mobile>
  </contact>
</contacts>') from dual;

update t set
    doc = replace (doc, '+7(923)-456-7891', '+7(925)-456-7892')
where instr (doc, '+7(923)-456-7891')>0;

1 row updated.

В противном случае, следует проанализировать, в каких узлах какие значения хранятся, чтобы на основе этого решить, эффективней ли будет обновлять документ как текст или стоит его обрабатывать другими инструментами, например XQuery.

Пример запроса для анлиза структуры XML документа:

select id, nodePath, nodeValue 
from t, xmlTable ('              
    for $i in $doc/descendant-or-self::*
        return 
            <element>
                <elpath> {$i/string-join(ancestor-or-self::*/name(.), ''/'')} </elpath>
                <eltext> {$i/text()}</eltext>
            </element>' passing  xmlType (doc) as "doc" columns 
    nodePath  varchar2(100) path '//elpath',
    nodeValue varchar2(100) path '//eltext' )
/
        ID NODEPATH                         NODEVALUE       
---------- -------------------------------- ----------------
         1 contacts                                         
         1 contacts/contact                                 
         1 contacts/contact/name            Ivan Ivanov     
         1 contacts/contact/phone           123-456-7890    
         1 contacts/contact                                 
         1 contacts/contact/name            Vasya Pupkin    
         1 contacts/contact/mobile          +7(925)-456-7892
→ Ссылка