PL/SQL Обноление CLOB содержащий XML
Столкнулась со следующий необходимостью обновить информацию в поле таблицы (формат CLOB) содержащее XML информацию с тэгами. Конкректно тэги в которых будет лежать информация не известны, например мне нужно обновить телефон клиента. Вопрос как сделать это наиболее быстро. На текущий момент сделала реализацию обновления следующим образом :
- завела переменную типа varchar(4000); -- переменная для входных данных
- считываю данные и записываю их в переменную select dbms_lob.substr(t.request, dbms_lob.getlength(t.request),1) as request into variable from logfiles t
- а дальше уже использую регулярные выражения ищу информацию с маской содержащий телефон REGEXP_SUBSTR()
- полученные данные передаю в clob, т.е. его обновлняю. Метод рабочий, но каждый раз clob записывать в varchar учитывая миллионы( как минимум) будет слишком затратно по ресурсам и долго. А выдержит ли БД такие нагрузки далеко не понятно (т.к. информации о технических сведениях вовсе не известны). Принимаются дельные советы и ссылки на статьи. Заранее спасибо.
Ответы (1 шт):
Если заранее известно, что и чем заменять, то стандартные функции по поиску и замене текста также реаботают для 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