Есть запрос:
select
nvl(extractvalue(xmltype(p.src_doc, 871), '//*:' || pd.name),
extractvalue(xmltype(p.src_doc, 871), '*/*[local-name()="AdditionalData"][*[local-name()="Name"]="' || pd.name || '"][1]/*[local-name()="Value"]')) as elm_value,
pd.guid as param_guid,
p.guid as pmnt_guid
from
payments p
join services s
on p.srv_guid = s.guid
join parameters_definitions pd
on s.guid = pd.srv_guid
left outer join pmnt_elements_values elm
on p.guid = elm.pmnt_guid and pd.guid = elm.param_guid
where
elm.guid is null and p.src_doc is not null;
В принципе корректно парсит XML в clob, но иногда может возникнуть исключение:
ORA-31011: сбой разбора XML
ORA-19202: Возникла ошибка при обработке XML
LPX-00601: Invalid token in: '//*: PAYMENTTYPE '
31011. 00000 - "XML parsing failed"
*Cause: XML parser returned an error while trying to parse the document.
*Action: Check if the document to be parsed is valid.
Проблема в том, что некоторые XML корректны, некоторые нет, таблица довольно объемна. Единого примера XML тоже дать не могу, так как все XML-документы корректны в рамках своей схемы, но по понятным причинам имеют разные значения в нодах, разные неймспейсы и атрибуты в некоторых нодах.
Можно ли как-то обойти/проигнорировать/обработать исключения разбора XML? Можно ли хотя бы как-то получить понимание где конкретно и на чем разваливается парсер?
Версия: Oracle Database 11g Enterprise Edition.
Ответ
Надо обернуть всю логику по разбору XML в функцию, которая обработает исключения и запишет полную информацию об ошибках, например, в таблицу. Как-то так:
create table parseErrors (guid raw (16), errm varchar2 (4000), created timestamp);
create or replace function myXmlParser (docGuid raw, doc clob) return varchar2 is
procedure saveParseError (guid raw, errm varchar2) is
pragma autonomous_transaction;
begin
insert into parseErrors values (guid, errm, systimestamp);
commit;
end ;
begin
-- **здесь необходимая логика, в которой может возникнуть ошибка**
return xmlType (doc).getStringVal ();
exception when others then
saveParseError (docGuid, sqlerrm||chr(10)||sys.dbms_utility.format_error_backtrace());
return 'errorneous';
end myXmlParser;
/
Выборка для теста (вместо sys_guid() должна быть колонка с GUID из запроса):
select myXmlParser (sys_guid(), '
выведет:
RESULT
------------------------
Kакие были ошибки:
set lines 999
col errm for a40 wrapp
select * from parseErrors;
GUID ERRM CREATED
-------------------------------- ---------------------------------------- -----------------------------
7106268B980F02D3E0530A01A8C04FBB ORA-31011: XML parsing failed 2018-07-15 12:32:41,204757000
ORA-06512: at "SYS.XMLTYPE", line 272
ORA-06512: at "DB.MYXMLPARSER", line 10
PS В вопросе мало информации по локализации причины ошибки, но думаю ссылки на похожие топики тут и тут будут полезны.
Комментариев нет:
Отправить комментарий