我在oracle 10数据库中有一个表,其中包含一个带有BLOB(不是CLOB)的字段。该BLOB包含大约300字节的固定大小的头,后面是XML文档。 blob的大小可能大约为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
我知道这个数据组织不是最理想的,但不能改变。
答案 0 :(得分:1)
好的,首先你必须得到XML部分。假设标题和XML都是字符数据,并且标题是固定长度,我可能会使用
的组合dbms_lob.converttoclob将blob变为clob dbms_lob.substr获取具有XML部分的clob xmltype.createXML(clob)将XML分配给xmltype xmltype.extract以应用xpath表达式
如果标题不是字符数据,您仍然可以使用dbms_lob.substr,但它将返回您需要转换的RAW。如果标题长度不固定,则可以搜索该位置
因此,根据注释,使用类似的东西构建一个具有所需内容的clob,其中offset是实际XML开头的字节数。修改以传入blob或clob。然后在末尾应用你的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;