Oracle запрос анализирует XML из BLOB-объектов с заголовком - PullRequest
1 голос
/ 14 июля 2011

У меня есть таблица в базе данных Oracle 10, содержащая поле с BLOB (не CLOB).Этот большой двоичный объект содержит заголовок с фиксированным размером около 300 байтов, за которым следует документ XML.Размер блоба может составлять до 1 мегабайта.Я хотел бы создать запрос SQL, который использует XQUERY в этом документе для извлечения информации из XML.

Итак, структура примерно равна:

create table tbl(id integer, data blob);

insert into tbl(id,data) value(1,'HEADER <?xml version="1.0"><data>
  <row key="k1" value="v11"/>
  <row key="k2" value="v12"/></data>');

insert into tbl(id,data) value(2,'HEADER <?xml version="1.0"><data>
  <row key="k1" value="v21"/>
  <row key="k1" value="v21B"/>
  <row key="k2" value="v22"/></data>');

Я бы хотел запрос к этой таблице, который при заданном ключе k1 возвращает значения v11, v21 и v21B

Я знаю, что эта организация данных неоптимальна, но ее нельзя изменить.

1 Ответ

1 голос
/ 14 июля 2011

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

dbms_lob.converttoclob, чтобы превратить каплю в сгусток dbms_lob.substr для получения сгустка с частью XML xmltype.createXML (clob), чтобы назначить XML для вашего xmltype xmltype.extract для применения вашего выражения xpath

Если заголовок не является символьными данными, вы все равно можете использовать dbms_lob.substr, но он вернет RAW, который вам нужно будет преобразовать. Если длина заголовка не фиксирована, вы можете найти местоположение

Итак, основываясь на комментариях, используйте что-то вроде этого, чтобы создать clob, который имеет то, что вы хотите, где offset - это количество байтов до начала вашего фактического XML. Модифицируйте, чтобы передать ваш блоб или клоб. Затем примените ваш xpath в конце вместо моего dbms_output.

declare
   v_buffer varchar2(32767);
   v_offset integer := 5;
   v_xml xmltype;
   v_clob clob;
   v_input clob := 'xxxx<?xml version="1.0" encoding="UTF-8"?><test>This is a test</test>';
   i integer := 0;
begin
   dbms_lob.createtemporary (v_clob,true);
   v_buffer := dbms_lob.substr(v_input,32767,v_offset);
   while length (v_buffer) > 0 loop
      v_clob := v_clob || v_buffer;
      i := i + 1;
      v_buffer := dbms_lob.substr(v_input,32767, v_offset + i * 32767);
   end loop;
   dbms_output.put_line ('x'||v_clob||'x');
   v_xml := xmltype.createXML (v_clob); 
   dbms_lob.freetemporary (v_clob);
   dbms_output.put_line (v_xml.getclobval);
end;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...