Oracle SQL - 如何从BLOB中删除前导字节(并以RAW形式返回)?

whi*_*ose 5 oracle plsql blob pentaho-report-designer

我正在编写一个报告工具(Pentaho Report Designer)的查询,我需要检索一些存储在Oracle 11数据库中的jpgs.诀窍是慢跑(存储为BLOB)包括我需要删除的12字节头(由另一个应用程序添加).报告工具还要求将数据作为RAW数据返回.

我遇到的问题似乎是我找到的用于操作BLOB的函数/过程都对它们有严格的大小/长度限制.

使用DBMS_LOB.SUBSTR(dbfile.filedata,2000,12),此查询与我可以获得的工作一样接近:

select DBMS_LOB.SUBSTR(dbfile.filedata,2000,12) as filedata
from bms_0002005_251 safety
inner join bms_9999999_100 file02 on safety.bms_id = file02.bms_fk_0002005_839_ID
inner join bms_9999999_104 inc on safety.bms_fk_0002005_844_id = inc.bms_id
left join bms_dbfiles dbfile on file02.bms_9999999_40 = dbfile.uniqueid
Run Code Online (Sandbox Code Playgroud)

对于<= 2000字节的图像,这完全有效,剥离12字节标头并返回原始数据,如FFD8FFE000104A46494600010201006000600000FFEE000E41646F626500640000000001 ...等

但是对于较大的图像(大多数图像)2000是不够的,但是一旦我将子字符串长度增加到2001,查询就会失败:

ORA-06502:PL/SQL:数字或值错误:原始变量长度太长ORA-06512:第1行06502. 00000 - "PL/SQL:数字或值错误%s"

这是我最接近的,但长话短说 - 在单个查询中是否有任何方法我可以从大型BLOB中删除前12个字节并将数据作为RAW返回?

diz*_*iaq 1

一般来说,考虑到ORA-14553. Blob 变量是指向数据的指针,但不是数据本身。这就是为什么像DBMS_LOB.SUBSTRreturn not BLOBor CLOB, but RAWor CHAR- 这样的函数,因为最后类型的数据(变量)可以直接在 RAM 中使用。

因此,要查询修改后的 blob(从头部删除 12 个字节),我们需要在查询之前创建并存储修改后的 blob。根据业务需求,它可以就地完成,也可以通过创建新的 blob 并保留原始数据来完成。就这个问题而言,我想我们无法就地修改原始斑点。

显然,第二种方式(保留原件)是更耗费资源的方式。

解决方案大图:

  1. 确定要查询的 blob 列表
  2. 对于列表中的每个项目,创建并存储修改后的 blob(例如,修剪 12 个字节),并通过 id 链接到原始数据
  3. 运行返回修改后的 blob 的查询
  4. 删除修改的 blob(在查询游标被消耗后或按计划立即删除)

这导致的问题多于它解决的问题:

  • 需要清理修改过的 blob
  • 原始和修改的同步
  • 存储数据量加倍
  • 其他惊喜

我想有一个不那么痛苦的解决方案 - 在使用查询结果的外部编写代码并在数据库外部修改 blob 数据