读取 Oracle 中的 BLOB 列 table
Reading BLOB column in oracle table
我有一个 table 列表,其中包含以下几列:
create table tbl (id number,
colA BLOB,
ColB BLOB,
Insert_time timestamp(0)
)
当我在下面查询 运行 时,它工作正常:
select id,
substr(substr(utl_raw.cast_to_varchar2( dbms_lob.substr( utl_compress.lz_uncompress(tbl.colA), 2000, 1) ),instr(utl_raw.cast_to_varchar2( dbms_lob.substr( utl_compress.lz_uncompress(tbl.ColA), 2000, 1) ),'MeterReadingReasonCode',1),25),24,2) first
--substr(substr(utl_raw.cast_to_varchar2( dbms_lob.substr( utl_compress.lz_uncompress(tbl.ColB), 2000, 1) ),instr(utl_raw.cast_to_varchar2( dbms_lob.substr( utl_compress.lz_uncompress(tbl.ColB), 2000, 1) ),'MeterReadingTypeCode',1),23),22,2) second
from tbl
where
tbl.INSERT_TIME >= To_Date('04-01-2020 12:00:00 AM' ,'dd-mm-yyyy hh12:mi:ss AM')
and tbl.INSERT_TIME <= To_Date('04-08-2020 11:00:00 PM' ,'dd-mm-yyyy hh12:mi:ss AM')
但是当我在下面的 运行 时它抛出错误:
select id,
substr(substr(utl_raw.cast_to_varchar2( dbms_lob.substr( utl_compress.lz_uncompress(tbl.colA), 2000, 1) ),instr(utl_raw.cast_to_varchar2( dbms_lob.substr( utl_compress.lz_uncompress(tbl.ColA), 2000, 1) ),'MeterReadingReasonCode',1),25),24,2) first
substr(substr(utl_raw.cast_to_varchar2( dbms_lob.substr( utl_compress.lz_uncompress(tbl.ColB), 2000, 1) ),instr(utl_raw.cast_to_varchar2( dbms_lob.substr( utl_compress.lz_uncompress(tbl.ColB), 2000, 1) ),'MeterReadingTypeCode',1),23),22,2) second
from tbl
where
tbl.INSERT_TIME >= To_Date('04-01-2020 12:00:00 AM' ,'dd-mm-yyyy hh12:mi:ss AM')
and tbl.INSERT_TIME <= To_Date('04-08-2020 11:00:00 PM' ,'dd-mm-yyyy hh12:mi:ss AM')
我的意思是说,如果我 select 只有 1 个 blob 列要读取,那么日期过滤器就可以正常工作。
但是当我在 where 子句中 select 两个带有日期过滤器的 BLOB 列时,它会抛出以下错误:
ORA-29261: bad argument
ORA-06512: at "SYS.UTL_SYS_COMPRESS", line 60
ORA-06512: at "SYS.UTL_SYS_COMPRESS", line 230
ORA-06512: at "SYS.UTL_COMPRESS", line 89
29261. 00000 - "bad argument"
*Cause: A bad argument was passed to the PL/SQL API.
*Action: Check the arguments passed to the PL/SQL API and retry the call.
这简单意味着(如异常所示)在列 ColLB
中不包含有效的解压值。
测试表明这很可能是具有 NULL
值的列 - 请参阅下面的脚本。
create table tbl (ColB BLOB);
insert into tbl ( colb)
values(null);
select
utl_compress.lz_uncompress(tbl.ColB)
from tbl
;
ORA-29261: bad argument
ORA-06512: at "SYS.UTL_SYS_COMPRESS", line 56
ORA-06512: at "SYS.UTL_SYS_COMPRESS", line 226
ORA-06512: at "SYS.UTL_COMPRESS", line 89
请注意,如果您存储的非 NULL
值已损坏(即未采用压缩格式),您会看到不同的异常情况
insert into tbl ( colb)
values(HEXTORAW('cafe'));
select
utl_compress.lz_uncompress(tbl.ColB)
from tbl
;
ORA-29294: A data error occurred during compression or uncompression.
ORA-06512: at "SYS.UTL_SYS_COMPRESS", line 56
ORA-06512: at "SYS.UTL_SYS_COMPRESS", line 226
ORA-06512: at "SYS.UTL_COMPRESS", line 89
因此,作为一种解决方法,您应该使用针对 NULL
的 CASE
语句测试来保护您的表达式
select
case when colB is not NULL then
substr(substr(utl_raw.cast_to_varchar2( dbms_lob.substr( utl_compress.lz_uncompress(tbl.ColB), 2000, 1) ),instr(utl_raw.cast_to_varchar2( dbms_lob.substr( utl_compress.lz_uncompress(tbl.ColB), 2000, 1) ),'MeterReadingTypeCode',1),23),22,2)
end as second
from tbl
我有一个 table 列表,其中包含以下几列:
create table tbl (id number,
colA BLOB,
ColB BLOB,
Insert_time timestamp(0)
)
当我在下面查询 运行 时,它工作正常:
select id,
substr(substr(utl_raw.cast_to_varchar2( dbms_lob.substr( utl_compress.lz_uncompress(tbl.colA), 2000, 1) ),instr(utl_raw.cast_to_varchar2( dbms_lob.substr( utl_compress.lz_uncompress(tbl.ColA), 2000, 1) ),'MeterReadingReasonCode',1),25),24,2) first
--substr(substr(utl_raw.cast_to_varchar2( dbms_lob.substr( utl_compress.lz_uncompress(tbl.ColB), 2000, 1) ),instr(utl_raw.cast_to_varchar2( dbms_lob.substr( utl_compress.lz_uncompress(tbl.ColB), 2000, 1) ),'MeterReadingTypeCode',1),23),22,2) second
from tbl
where
tbl.INSERT_TIME >= To_Date('04-01-2020 12:00:00 AM' ,'dd-mm-yyyy hh12:mi:ss AM')
and tbl.INSERT_TIME <= To_Date('04-08-2020 11:00:00 PM' ,'dd-mm-yyyy hh12:mi:ss AM')
但是当我在下面的 运行 时它抛出错误:
select id,
substr(substr(utl_raw.cast_to_varchar2( dbms_lob.substr( utl_compress.lz_uncompress(tbl.colA), 2000, 1) ),instr(utl_raw.cast_to_varchar2( dbms_lob.substr( utl_compress.lz_uncompress(tbl.ColA), 2000, 1) ),'MeterReadingReasonCode',1),25),24,2) first
substr(substr(utl_raw.cast_to_varchar2( dbms_lob.substr( utl_compress.lz_uncompress(tbl.ColB), 2000, 1) ),instr(utl_raw.cast_to_varchar2( dbms_lob.substr( utl_compress.lz_uncompress(tbl.ColB), 2000, 1) ),'MeterReadingTypeCode',1),23),22,2) second
from tbl
where
tbl.INSERT_TIME >= To_Date('04-01-2020 12:00:00 AM' ,'dd-mm-yyyy hh12:mi:ss AM')
and tbl.INSERT_TIME <= To_Date('04-08-2020 11:00:00 PM' ,'dd-mm-yyyy hh12:mi:ss AM')
我的意思是说,如果我 select 只有 1 个 blob 列要读取,那么日期过滤器就可以正常工作。 但是当我在 where 子句中 select 两个带有日期过滤器的 BLOB 列时,它会抛出以下错误:
ORA-29261: bad argument
ORA-06512: at "SYS.UTL_SYS_COMPRESS", line 60
ORA-06512: at "SYS.UTL_SYS_COMPRESS", line 230
ORA-06512: at "SYS.UTL_COMPRESS", line 89
29261. 00000 - "bad argument"
*Cause: A bad argument was passed to the PL/SQL API.
*Action: Check the arguments passed to the PL/SQL API and retry the call.
这简单意味着(如异常所示)在列 ColLB
中不包含有效的解压值。
测试表明这很可能是具有 NULL
值的列 - 请参阅下面的脚本。
create table tbl (ColB BLOB);
insert into tbl ( colb)
values(null);
select
utl_compress.lz_uncompress(tbl.ColB)
from tbl
;
ORA-29261: bad argument
ORA-06512: at "SYS.UTL_SYS_COMPRESS", line 56
ORA-06512: at "SYS.UTL_SYS_COMPRESS", line 226
ORA-06512: at "SYS.UTL_COMPRESS", line 89
请注意,如果您存储的非 NULL
值已损坏(即未采用压缩格式),您会看到不同的异常情况
insert into tbl ( colb)
values(HEXTORAW('cafe'));
select
utl_compress.lz_uncompress(tbl.ColB)
from tbl
;
ORA-29294: A data error occurred during compression or uncompression.
ORA-06512: at "SYS.UTL_SYS_COMPRESS", line 56
ORA-06512: at "SYS.UTL_SYS_COMPRESS", line 226
ORA-06512: at "SYS.UTL_COMPRESS", line 89
因此,作为一种解决方法,您应该使用针对 NULL
CASE
语句测试来保护您的表达式
select
case when colB is not NULL then
substr(substr(utl_raw.cast_to_varchar2( dbms_lob.substr( utl_compress.lz_uncompress(tbl.ColB), 2000, 1) ),instr(utl_raw.cast_to_varchar2( dbms_lob.substr( utl_compress.lz_uncompress(tbl.ColB), 2000, 1) ),'MeterReadingTypeCode',1),23),22,2)
end as second
from tbl