求助:ORA-22994: 源偏移量超出源 LOB 的结尾的解决办法

[复制链接]
查看11 | 回复3 | 2008-1-2 17:35:53 | 显示全部楼层 |阅读模式
我在测试pCmsPersonInforAdd时出现了"ORA-22994: 源偏移量超出源 LOB 的结尾",我的操作如下:
步骤1:
CREATE SEQUENCE SEQ_PersonInfor
minvalue 1
maxvalue 999999999999999999999999999
start with 1
increment by 1
nocache;
步骤2:
create table tCmsPersonInfor(
dIntgPersonnelID INTEGER
not null,
dVch2PersonNameVARCHAR2(20),
dVch2Duty
VARCHAR2(20),
dVch2IdentifyVARCHAR2(20),
dVch2ContectPhoneVARCHAR2(20),
dBlobDrivLicence BLOB,
dBlobIdentifyLicence BLOB,
dBlobFactoryLicenceBLOB,
dVch2Remark
VARCHAR2(200),
constraint PK_TCMSPERSONINFOR primary key (dIntgPersonnelID)
);

步骤3:
create or replace procedure pCmsPersonInforAdd
(
viVch2PersonName VARCHAR2,--人员姓名
viVch2Duty VARCHAR2,--职务
viVch2Identify VARCHAR2(20),--身份证号
viVch2ContectPhone VARCHAR2(20),--联系电话
viVch2DrivLicence VARCHAR2(20),--驾照扫描件名称
viVch2IdentifyLicence VARCHAR2(20),--身份证扫描件名称
viVch2FactoryLicence VARCHAR2(20),--出场证扫描件名称
viVch2Remark VARCHAR2(20),--备注
voIntReturns OUT INT
)
as
mNumCount number;
mBflFileloc bfile;
mIntMount int;
mIntDestOffset int := 1;
mIntSrcOffset int := 1;
type emp_varchar2_array is table of varchar2(20) index by binary_integer;
mScanPictureName emp_ssn_array;
type emp_blob_array is table of blob index by binary_integer;
mScanPictureBlob emp_blob_array;
begin
mScanPictureName(1) := viVch2DrivLicence;
mScanPictureName(2) := viVch2IdentifyLicence;
mScanPictureName(3) := viVch2FactoryLicence;

insert into tCmsPersonInfor (dIntgPersonnelID,dVch2PersonName,dVch2Duty,dVch2Identify,dVch2ContectPhone,dBlobDrivLicence,dBlobIdentifyLicence,dBlobFactoryLicence,dVch2Remark)
values (SEQ_PersonInfor.nextval,viVch2PersonName,viVch2Duty,viVch2Identify,viVch2ContectPhone,empty_blob(),empty_blob(),empty_blob(),viVch2Remark);
select max(dIntgPersonnelID) into mNumCount from tCmsPersonInfor;
select dBlobDrivLicence,dBlobIdentifyLicence,dBlobFactoryLicence into mScanPictureBlob(1),mScanPictureBlob(2),mScanPictureBlob(3) from tCmsPersonInfor where dIntgPersonnelID = mNumCount for update;

for i in 1..mScanPictureName.count loop
mBflFileloc := bfilename('UPFILE_DIR',mScanPictureName(i));
dbms_lob.fileopen(mBflFileloc,0);

mIntMount := dbms_lob.getlength(mBflFileloc);
dbms_lob.loadblobfromfile(mScanPictureBlob(i),mBflFileloc,mIntMount,mIntDestOffset,mIntSrcOffset);
dbms_lob.fileclose(mBflFileloc);
end loop;
voIntReturns := 1;
commit;
exception
when others then
voIntReturns := -1;
rollback;
end;
/

进行测试入下图:


1.gif (790.55 KB, 下载次数: 7)
下载附件
2007-12-27 18:42 上传

我该如何处理?谢谢指点
回复

使用道具 举报

千问 | 2008-1-2 17:35:53 | 显示全部楼层
在循环里,条件判断每次计算偏移量,小于CLOB的最大结尾时,按照每次读取的BUFFER长度读取;
如果超过了CLOB的最大结尾时,则把CLOB的最大结尾减去 (上次读取的位置+1),作为读取的buffer长度---其实就是算这个值,处理最后读取的字符串。处理完退出循环。
你自己试下吧,懒得写了
回复

使用道具 举报

千问 | 2008-1-2 17:35:53 | 显示全部楼层
大哥能不能说的详细点,我才接触Oracle
回复

使用道具 举报

千问 | 2008-1-2 17:35:53 | 显示全部楼层
修改:
在代码LOOP 开始的地方加上如下2行
mIntDestOffset := 1;
mIntSrcOffset := 1;
看该函数的定义:
DBMS_LOB.LOADCLOBFROMFILE (
dest_lob IN OUT NOCOPY BLOB,
src_bfileIN
BFILE,
amount IN
INTEGER,
dest_offsetIN OUT
INTEGER,
src_offset IN OUT
INTEGER,
bfile_csid IN
NUMBER,
lang_context IN OUT
INTEGER,
warningOUT
INTEGER);
看到么
dest_offsetIN OUT
INTEGER,
src_offset IN OUT
INTEGER,
是IN OUT所以会修改,dest_offset , src_offset的值的,所以在循环开始的地方加上2个付值语句就好了.

这两个值的默认为1,但读区后会修改成次LOAD后的最后一个字节的位置
至于为什么要返回该参数,我猜想是由于,存在amount参数,那么可以,循环的 执行LOAD 1000个BIT直到读完,而不需要设定偏移.
顺便说:amount解释为:
Number of bytes to load from the BFILE. Use DBMS_LOB.LOBMAXSIZE to load until the end of the BFILE.
其中
The value of offset, amount, newlen, nth must not exceed the value lobmaxsize (4GB-1) in any DBMS_LOB subprogram.
所以该函数不能读取大于4GB-1个字节的文件,否则会截取,不过我没测试过,呵呵.
完!
[ 本帖最后由 bacel 于 2008-1-11 14:38 编辑 ]
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

主题

0

回帖

4882万

积分

论坛元老

Rank: 8Rank: 8

积分
48824836
热门排行