用oracle的blob存储图像时,一到post就出错(内详)(倾囊而出200分)!拜托拉!(200分)

  • 主题发起人 主题发起人 snowworm
  • 开始时间 开始时间
S

snowworm

Unregistered / Unconfirmed
GUEST, unregistred user!
MS: TMemoryStream;
image1.Picture.LoadFromFile(openpicturedialog1.FileName);
MS:=TMemoryStream.create;
Image1.Picture.Graphic.SaveToStream(MS);
MS.Position:=0;
Table1.EDIT;
TBlobField(Table1.FieldbyName('PHOTO')).LoadFromStream(MS);
MS.Position:=0;
MS.free;
Table1.Post;
运行到post就出错了,换了几种流存储方法,还是同样的错误:
ORA-22990: LOB locators cannot span transactions
Cause: A LOB locator selected in one transaction cannot be used in a differe
nt transaction.
Action: Re-select the LOB locator and retry the operation.
这是我在oracle主页找到的关于该错误的解析,但在程序中不知道怎么解决,还请赐教!
 

TBlobField(Table1.FieldbyName('PHOTO')).LoadFromStream(MS);
MS.Position:=0;
// MS.free;
Table1.Post;
 
var
bs: TBlobStream;

image1.Picture.LoadFromFile(openpicturedialog1.FileName);
Table1.EDIT;
bs:=TBlobStream.create(TBlobField(Table1.FieldbyName('PHOTO')),bmWrite);
Image1.Picture.Graphic.SaveToStream(bs);
bs.free;
Table1.Post;
 
你的是bmp吗?是bmp的话改成:
Image1.Picture.Bitmap.SaveToStream(bs);
 
存的是bmp文件。
都试过了,还是不行啊!还有没有其他方法?
 
还是一样的错误
 
用流的方式
var
FS: TFileStream;
begin
if not (Query1.State in [dsInsert, dsEdit]) then Query1.Insert;
FS := TFileStream.Create('c:/Windows/Winlogo.bmp', fmOpenRead);
try
Query1Images.LoadFromStream(FS);
finally
FS.Free;
end;
Query1.Post;
end;
 
试过了所有流的方法,还是一样的错误,我觉得关键还是在于要重新选择lob定位器,
oracle的错误解析说得很清楚,但就不知道怎么在程序中实现。
ORA-22990: LOB locators cannot span transactions
Cause: A LOB locator selected in one transaction cannot be used in a differe
nt transaction.
Action: Re-select the LOB locator and retry the operation.
 
oracle的blob字段,大家支持的都不是很好,包括bde
比较好的有:bde通过oracle带来的odbc
ado通过oracle带来的oledb probvider
ms带来的oledb和odbc都不支持blob,
bde的oracle驱动程序则支持的不是很好,不过borland有最新版的bde下载,可以试试
 
那就用ODAC吧,最好的for oracle控件.
 
bde通过oracle带来的odbc
具体怎么设置?谢谢
 
先用
insert into table (blob) values (empty_blob)
插入一个空的定位符
再用table写
不能用query的缓存更新
用bde直接连oracle
 
你加上事务看看,我以前也遇到过。
 
同意 沉香屑。
我以前就是这样做的。
 
按照 沉香屑 的方法试了一下,发现只有把Table1的cachedupdates设成true,把执行
insert into table (blob) values (empty_blob)
的Query1的cachedupdates设成false才不会出错,但这样调用post时,
好象图像实际上没存进数据库,第二次运行程序数据库里没有图像。
是不是不能用post,要用其他的方法?
 
POST之后加上
table1.ApplyUpdates;
table1.CommitUpdates;
写入数据库时还是一样的错误,我的实现方法就是在上面的代码的
Table1.EDIT;
前面加上
query1.Close;
query1.SQL.Clear;
query1.SQL.Add('INSERT INTO MANAGER.TABLE1(NO,PHOTO) VALUES (''004'',empty_blob())');
query1.ExecSQL;
这几句执行都没问题,也加入了一条新的纪录,我想是不是要取得BLOB的定位器才能写进去,
但就是不知道怎么得到,我对其中的原理不清楚,还请说的详细点,最好给出源代码,
拜托了!
 
oracle中blob字段中存的是一个指针,叫做定位符,所以要先插入有效的空定位符
oracle中的操作会自动的调用事务,在commit或连接断开后才永久修改回数据库
所以写blob不能用bde的缓存更新,并且要显式的使用事务


在插入empty_blob后commit
具体这样写:
Query1.SQL.Clear;
Query1.SQL.Add('begin');
Query1.SQl.Add('insert into TABLE1(NO,PHOTO) values (''1000'',empty_blob());');
Query1.SQl.Add('commit;');
Query1.SQl.Add('end;');
Query1.ExecSQL;
在修改blob时显式的调用事务:
Database1.StartTransaction;
try
if Table1.Active=False then
Table1.open;
Table1.locate('no','1000',[loCaseInsensitive]);
Table1.Edit;
MS:=TMemoryStream.Create;
Image1.Picture.Graphic.SaveToStream(MS);
tblobfield(Table1.FieldByName('zp')).LoadFromStream(MS);
Table1.Post;
Table1.Close;
Ms.Free;
Database1.Commit;
except
Database1.Rollback;
end;
 
沉香屑大虾的回答让小弟五体投地,以后还请多多指教。
 
后退
顶部