Oracle 查询从带有标头的 blob 中解析 XML

发布于 2024-11-23 23:18:39 字数 697 浏览 1 评论 0原文

我在 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

我知道这个数据组织不是最优的,但无法更改。

I have a table in an oracle 10 database, containing a field with a BLOB (not CLOB). This BLOB contains a fixed-size header of about 300 bytes, followed by an XML document. The blob might have a size up to about 1 megabyte. I'd like to create an SQL query which uses XQUERY on this document to extract information from the XML.

So the structure is, roughly:

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>');

I'd like a query on this table which, when given key k1, returns values v11,v21 and v21B

I know this data organisation is suboptimal, but it can't be changed.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

暗地喜欢 2024-11-30 23:18:39

好的,首先您必须获取 XML 部分。假设标头和 XML 都是字符数据,并且标头是固定长度,我可能会使用

dbms_lob.converttoclob 的组合将 blob 转换为 clob
dbms_lob.substr 获取具有 XML 部分的 clob
xmltype.createXML (clob) 将 XML 分配给您的 xmltype
xmltype.extract 应用您的 xpath 表达式

如果标头不是字符数据,您仍然可以使用 dbms_lob.substr,但它将返回您需要转换的 RAW。如果 header 不是固定长度,可以搜索 header 的位置

因此,根据注释,使用类似的内容来构建一个包含您想要的内容的 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;

OK, so first you have to get the XML part. Assuming that the header and XML are both character data, and the header is a fixed length, I'd probably use a combination of

dbms_lob.converttoclob to turn the blob into a clob
dbms_lob.substr to get a clob that has the XML portion
xmltype.createXML (clob) to assign the XML to your xmltype
xmltype.extract to apply your xpath expression

If the header isn't character data, you can still use dbms_lob.substr but it will return a RAW which you'll need to convert. If the header isn't fixed length, you can search for the location of the

So, based on the comments, use something like this to build a clob that has what you want, where offset is the number of bytes to the start of your actual XML. Modify to pass in your blob or clob. Then apply your xpath at the end instead of my 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;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文