我想将OleContainer保存在SQL2000的文件中,然后再读出到另一个OleContainer中,保存时没有问题,但从数据库读出的时候就一直出错!!!代码如下,请高手指点!unit Unit1;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, DB, ADODB, ExtCtrls, Grids, DBGridEh, OleCtnrs, IBBlob;type
TForm1 = class(TForm)
con1: TADOConnection;
dlgOpen1: TOpenDialog;
qry1: TADOQuery;
qry1FileID: TAutoIncField;
qry1FileName: TStringField;
qry1FileData: TBlobField;
dbge1: TDBGridEh;
pnl1: TPanel;
btn1: TButton;
ds1: TDataSource;
btn2: TButton;
dlgSave1: TSaveDialog;
OleContainer1: TOleContainer;
OleContainer2: TOleContainer;
procedure btn1Click(Sender: TObject);
procedure btn2Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;var
Form1: TForm1;implementation{$R *.dfm}procedure TForm1.btn1Click(Sender: TObject);
var
strFileStream:TMemoryStream;
begin
strFileStream:=TMemoryStream.Create;
OleContainer1.SaveToStream(strFileStream);
with qry1 do
begin
Append;
TBlobField(FieldByName('FileData')).LoadFromStream(strFileStream);
Post;
end;
end;procedure TForm1.btn2Click(Sender: TObject);
var
strFileStream:TMemoryStream;
begin
with qry1 do
begin
strFileStream:=TMemoryStream.Create;
strFileStream.Clear;
TBlobField(FieldByName('FileData')).SaveToStream(strFileStream);
OleContainer2.LoadFromStream(strFileStream);
end;
end;end.
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, DB, ADODB, ExtCtrls, Grids, DBGridEh, OleCtnrs, IBBlob;type
TForm1 = class(TForm)
con1: TADOConnection;
dlgOpen1: TOpenDialog;
qry1: TADOQuery;
qry1FileID: TAutoIncField;
qry1FileName: TStringField;
qry1FileData: TBlobField;
dbge1: TDBGridEh;
pnl1: TPanel;
btn1: TButton;
ds1: TDataSource;
btn2: TButton;
dlgSave1: TSaveDialog;
OleContainer1: TOleContainer;
OleContainer2: TOleContainer;
procedure btn1Click(Sender: TObject);
procedure btn2Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;var
Form1: TForm1;implementation{$R *.dfm}procedure TForm1.btn1Click(Sender: TObject);
var
strFileStream:TMemoryStream;
begin
strFileStream:=TMemoryStream.Create;
OleContainer1.SaveToStream(strFileStream);
with qry1 do
begin
Append;
TBlobField(FieldByName('FileData')).LoadFromStream(strFileStream);
Post;
end;
end;procedure TForm1.btn2Click(Sender: TObject);
var
strFileStream:TMemoryStream;
begin
with qry1 do
begin
strFileStream:=TMemoryStream.Create;
strFileStream.Clear;
TBlobField(FieldByName('FileData')).SaveToStream(strFileStream);
OleContainer2.LoadFromStream(strFileStream);
end;
end;end.
------------------
procedure TicwinLogFrm.ReadStreamToDataField(ole: TOleContainer;
DataSource: TDataSource; fieldName: string);
var
stream : TStream;
begin
stream :=
DataSource.DataSet.CreateBlobStream(DataSource.DataSet.fieldbyname(fieldName), bmRead);
try
ole.loadFromStream(stream);
finally
stream.free;
end;
end;procedure TicwinLogFrm.LoadRecordFromDataBase(recNo: integer);
// stream := DataSource.DataSet.CreateBlobStream(DataSource.DataSet.fieldbyname(fieldName),bmRead);
begin
//调用OLE对象为用户编辑用try
//if recNo <> -1 then //初始值为-1
// DBGrid.SelectedIndex := recNo;
caption := '用户:' + ADOQuery.FieldByName('User').AsString +
'上次添加时间:' + FormatDateTime('yyyy-mm-dd hh:nn:ss',
ADOQuery.FieldByName('DATETIME').AsDateTime);
if ADOQuery.FieldByName('Modified').AsBoolean = true then
caption := caption + '--- 被修改过'
else
caption := caption + '--- 还没有被修改过';caption := caption + inttostr(recNo) + '/' +
inttostr(ADOQuery.RecordCount);//(ADOQuery.FieldByName('WorkRec') as TBlobField).SaveToStream(oleDY);
ReadStreamToDataField(OleContainer, DataSource, 'WorkRec'); //这里的DataSource不能是ADOQuery.DataSource
finallyend;
end;procedure TicwinLogFrm.AddStreamToDataField(ole: TOleContainer;
DataSource: TDataSource; fieldName: string);
var
stream : TStream;
begin
stream :=
DataSource.DataSet.CreateBlobStream(DataSource.DataSet.fieldbyname(fieldName), bmwrite);
try
ole.SaveToStream(stream);
finally
stream.free;
end;
end;procedure TicwinLogFrm.AddRecordToDataBase;
// stream := DataSource.DataSet.CreateBlobStream(DataSource.DataSet.fieldbyname(fieldName),bmwrite);
begin
try
with ADOQuery do
begin
append;
end;
ADOQuery.FieldByName('User').AsString := 'o4icwin';
ADOQuery.FieldByName('DATETIME').AsDateTime := now();
//(ADOQuery.FieldByName('WorkRec') as TBlobField).LoadFromStream(OleStream);
AddStreamToDataField(OleContainer, DataSource, 'WorkRec');
ADOQuery.FieldByName('Modified').AsBoolean := false;
ADOQuery.Post;
except
ADOQuery.Cancel;
ADOConnection.RollbackTrans;
end;
end;
存入流:
Procedure SaveToStream(ADOTable1: TAdoTable)
var
vStream: TMemoryStream;
begin
try
try
vStream := TMemoryStream.Create;
vStream.Clear;
OleContainer1.SaveToStream(vStream);
vStream.Position := 0;
ADOTable1.Append;
TBlobField(ADOTable1.FieldByName("BlobField")).LoadFromStream(vStream);
ADOTable1.Post;
finally
FreeAndNil(vStream);
end;
except
exit;
end;
end;
读取流:
procedure LoadFromStream(ADOTable1: TAdoTable)
var
//注意:这里要用TADOBlobStream,如果用TMemoryStream等流类,则会出现错误
//OleContainer的二进制流格式和Access的二进制流格式不同
//TADOBlobStream是专门用来Access的流转化的,TADOBlobStream继承自TMemoryStream
vStream: TADOBlobStream;
begin
try
vStream := TADOBlobStream.Create(TBlobField(ADOTable1.FieldByName("BlobField")), bmread);
if (OleContainer1.State = osOpen) or (OleContainer1.State = osUIActive) then
begin
OleContainer1.DestroyObject;
end;
vStream.Position := 0;
Olecontainer1.LoadFromStream(vStream);
except
end;
end;
str: TADOBlobStream;
begin
ls_sql:='select * from tbDocument where id='+IntToStr(integer(Item.Data));
ADODoc.Close;
ADODoc.SQL.Clear;
ADODoc.SQL.Add(ls_sql);
ADODoc.Open;
ADODoc.Edit;
str:=TADOBlobStream.Create(Tblobfield(ADODoc.FieldByName('content')),bmRead);
str.Position:=0;
//锁定画面避免闪烁
LockwindowUpdate(OleContainer1.Handle);
LockwindowUpdate(Listview1.Handle);
OleContainer1.DestroyObject;
OleContainer1.LoadFromStream(TStream(str));
.....
OleContainer1.DoVerb(-1);
.....
另外还有两个关键:
数据库一定要使用image类型而不能使用text或其它大二进制类型;
必须使用TADOBlobStream