关于Blob域

dead_lee 2001-07-30 07:54:11
我将一个Zip文件存放到oralc8i的数据库中,取出来发现文件长度虽然没有变,但是却无法打开,用fc比较发现,在文件中间有一个字节被重复了一次,末尾又少了一个字节,程序在下面.诸位帮我看看.
测试用的zip文件有3m左右.

unit Mainfrm;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, DBTables, Grids, DBGrids, DB, ADODB, ExtCtrls, DBCtrls;

type
TForm1 = class(TForm)
ADOConnection1: TADOConnection;
ADOTable1: TADOTable;
DataSource1: TDataSource;
DBGrid1: TDBGrid;
db: TDatabase;
Table1: TTable;
DataSource2: TDataSource;
DBGrid2: TDBGrid;
adoSbtn: TButton;
bdeGbtn: TButton;
adoGbtn: TButton;
bdeSbtn: TButton;
DBNavigator1: TDBNavigator;
procedure bdeSbtnClick(Sender: TObject);
procedure bdeGbtnClick(Sender: TObject);
private
procedure IniOracleBlobField(Val: string);
public
{ Public declarations }
end;

var
Form1 : TForm1;

implementation

{$R *.dfm}

procedure TForm1.bdeSbtnClick(Sender: TObject);
var
KeyVal : string;
i : integer;
MS : TMemoryStream;
begin
Ms := TMemoryStream.Create();
db.StartTransaction;
for i := 1 to 10 do
with Table1 do
try
Randomize;
insert;
KeyVal := inttostr(random(100000));
FieldbyName('keyfield').AsString := KeyVal;
post;
IniOracleBlobField(KeyVal);
edit;
Ms.LoadFromFile('lady3_3.zip');
// Ms.SetSize(ms.Size + 1);
TBlobField(FieldbyName('blob_file')).LoadFromStream(ms);
post;
except
db.rollback;
Ms.Free;
abort;
end;
Ms.Free;
db.Commit;
end;

procedure TForm1.IniOracleBlobField(Val: string);
var
Query : TQuery;
begin
Query := TQuery.Create(self);
with Query do
begin
Sql.Clear;
Query.DatabaseName := 'leedb';
Sql.Add('UPDATE LEEBLOB Set BLOB_FILE=Empty_Blob() WHERE');
Sql.Add('KEYFIELD=:val');
Params[0].AsString := Val;
try
ExecSql;
except
ShowMessage('Blob域初始化错误');
end;
end;
end;

procedure TForm1.bdeGbtnClick(Sender: TObject);
begin
with table1 do
begin
TBlobField(FieldbyName('blob_file')).SaveToFile('bb.zip');
end;
end;

end.
...全文
216 20 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
20 条回复
切换为时间正序
请发表友善的回复…
发表回复
dead_lee 2001-08-02
  • 打赏
  • 举报
回复
up
BCB 2001-08-01
  • 打赏
  • 举报
回复
TMemoryStream用得不合适,改成文件流TFileStream
dead_lee 2001-08-01
  • 打赏
  • 举报
回复
up
dead_lee 2001-08-01
  • 打赏
  • 举报
回复
up
dead_lee 2001-08-01
  • 打赏
  • 举报
回复
修改bde的设置的确可以解决问题,实际上,以前的一个项目就是这样解决的,但是副作用也很明显:
你不能估计用户的Blob域的大小,客户端查询速度有影响.
dead_lee 2001-08-01
  • 打赏
  • 举报
回复
我测试了一下你的程序,你的程序应该不是针对Oracle的吧,如果用你的程序,Oracle会报错"只能在Long中插入改值",
如果将BlobType修改为ftOraBlob,则错误提示是"插入的值过大",Oracle手册说过,在插入Blob域值之前,要用Empty_Blob初始化,这也就是我的私有函数的作用.
用你的概念,我现在修改了一下插入的程序,但是取出来还是出错:
var
KeyVal, FileName : string;
i : integer;
MS : TFileStream;
Bf : TBlobField;
begin
FileName := 'D:\Leetest\BlobTest\lady3_3.zip';
Ms := TFileStream.Create(FileName, fmOpenRead);
db.StartTransaction;
for i := 1 to 10 do
with Table1 do
try
Randomize;
insert;
KeyVal := inttostr(random(100000));
FieldbyName('keyfield').AsString := KeyVal;
post;
IniOracleBlobField(KeyVal);
edit;
// Ms.SetSize(ms.Size + 1);
Bf := TBlobField(FieldbyName('blob_file'));
Bf.BlobType := ftOraBlob;
Bf.LoadFromStream(ms);
post;
except
db.rollback;
Ms.Free;
abort;
end;
Ms.Free;
db.Commit;
end;
powerlee 2001-08-01
  • 打赏
  • 举报
回复
参考下面代码,现在是什么类型文件都可以
//存文件到数据库
procedure TForm1.Button1Click(Sender: TObject);
begin
if OpenPictureDialog1.Execute then
begin

with Query1 do
begin
sql.clear;
sql.add('INSERT INTO TBIMAGE(id,filename,image) VALUES(1,:filename,:IMAGE)');
params[0].AsString := OpenPictureDialog1.FileName;
params[1].LoadFromFile(OpenPictureDialog1.FileName,ftGraphic);
execsql;
end;
end;

end;
//取到本地
var
t:TBlobField;
begin
with Query1 do
begin
sql.Clear;
sql.Add('select id,filename,image from tbimage');
open;

while not eof do
begin
SavePictureDialog1.InitialDir := ExtractFilePath(FieldByName('filename').AsString);
if SavePictureDialog1.Execute then
begin
t := FieldByName('IMAGE') As TBlobField;
t.SaveToFile(SavePictureDialog1.FileName);
end;
next;
end;
end;
end;
dana 2001-08-01
  • 打赏
  • 举报
回复
Delphi安装后BDE 的可用内存是2M,把它加大,修改BDE Adminstrator ->
Configuration ->system->init->sharedmemsize 为20480,20M!
建议使用ADO,BDE落伍了!
dana 2001-08-01
  • 打赏
  • 举报
回复
可能是bde的配置
dead_lee 2001-08-01
  • 打赏
  • 举报
回复
测试之后,错误依旧,而我现在怀疑是BDE设置里面关于Blob的块的大小和缓冲的块数的设置问题.所以要是手工用一个Buffer分批放到数据库可能可以解决问题,谁能给点提示代码.
另外,我用java测试放20m的文件都没有问题,应该错误不在oracle.(使用了buffer)
dead_lee 2001-07-31
  • 打赏
  • 举报
回复
la
光明山人 2001-07-31
  • 打赏
  • 举报
回复
看不出错来。不过,你为什么不直接用TBlobField.LoadFromFile方法而要增加一道手续?

另外,我对'lady3_3.zip'感兴趣,能不能给我发一个?prog@china.com 谢了。
ExitWindows 2001-07-31
  • 打赏
  • 举报
回复
up
dead_lee 2001-07-31
  • 打赏
  • 举报
回复
之所以多一道手续,是因为以前发现文档少了一个字节,以为是在转换中,少掉的字节被用做文件结束标志了.所以用stream,可以在保存到数据库时加一个字节,后来还是有问题,所以用fc仔细比较了一下,发现居然是中间就发生了错位.
lady3_3.zip是朱德庸的<涩女郎>漫画,在http://comicz.yeah.net/有下载,发邮件的话,文件就太大了(3m到5m)呢.
willsound 2001-07-31
  • 打赏
  • 举报
回复
gz
cobi 2001-07-31
  • 打赏
  • 举报
回复
gz
ExitWindows 2001-07-31
  • 打赏
  • 举报
回复
up
dead_lee 2001-07-30
  • 打赏
  • 举报
回复
能不能给个例子先.
powerlee 2001-07-30
  • 打赏
  • 举报
回复
你把分件切成小块再放入数据库中试试,我以前也是遇到类似的问题的
dead_lee 2001-07-30
  • 打赏
  • 举报
回复
up

5,928

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 开发及应用
社区管理员
  • VCL组件开发及应用社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧