本人写的三层系统中,要要用TClentDataSet向数据库(DB2)中插入Blob字段类型的数据,该数据是一个word的文件(write.doc),虽然插了进去(当然Blob字段也进去了),但是读出来的文件却比原文件小,却打不开读出的文件,提示文件无效,请高手指点,写的方法如下:
procedure TForm1.Button3Click(Sender: TObject);
var
stmFiles:Tfilestream;
strFileName:String;
begin
strFileName:='c:\write.doc';
stmFiles:=Tfilestream.Create(strFileName,fmOpenRead);
try
clientdataset1.CommandText:='insert into userid.xt_blob(YHDM,YHMC,YHKL,QM)'+' values(''vts'',''笑眯眯'',''111'',:BB1)';//QM是一个BLOB字段类型.
clientdataset1.Params.CreateParam(ftblob,'BB1',ptInput);
clientdataset1.Params.ParamByName('BB1').LoadFromStream(stmFiles,ftblob);
clientdataset1.Execute;
clientdataset1.Params.Clear;
finally
stmfiles.Free;
end;
end;
注意:
1.数据库的字段大小大于该文件的大小好几倍,所以不存在字段容量不够大的问题
2. 提交的是一个SQL的方法来插入,而不是要用什么Append,Post之类的方法来实现.
3. 本人测试过,用TQuery插入的方法插入后,又用TQuery将其文件读出,一切都正常.但是我用TQuery插入的word文档,用TClientDataSet读出是正常的,所以证明我读出的代码没有任何问题.而用TClientDataSet插入的记录,再用TClientDataSet或TQuery读出后的文件却比原文件小了点,所以文件读出的是坏的,说明用TClientDataSet写入时的文件就不正确了.
4.本人用的TSocketConnection连接,应用服务器端的BDE的BlobSize也设置的正确.所以该问题也排除.
5.但是如果插入的文件是一个txt文件类型时,一切都正确.
6.该问题也等到了一些网友的解答,但是经本人测试,好像也没有作用,也许是本人愚笨,写的不正确,所以烦请各为高手能给出一个完整的,经过测试过的方法,多谢大家的支持,问题一但解决,本人就散分!
本程序的读出代码如下(是正确的):
procedure TForm1.Button2Click(Sender: TObject);
var
stmFiles:Tfilestream;
strFileName:String;
begin
strFileName:='c:\read.doc';
if FileExists(strFileName) then
deletefile(strFileName);
stmFiles:=Tfilestream.Create(strFileName,fmCreate);
try
clientdataset1.CommandText:='select * from userid.xt_blob where yhdm=''vts'''; clientdataset1.Open;
clientdataset1.Last;
clientdataset1.First;
if clientdataset1.RecordCount >0 then
begin
TBlobField(clientdataset1.FieldByName('QM')).SaveToStream(stmFiles);
end;
finally
stmfiles.Free;
end;网友回答例子:
好像用DataSet的参数将BLOB字段的值传递给SQL只对BDE有效,对ClientDataSet或ADO是有问题的。
所以,ClientDataSet或ADODataSet一般都是通过建立其BLOB字段的流对象来实现流操作。TClientDataSet可建立TClientBlobStream类型的流,TADODataSet可建立TADOBlobStream类型的流。
在DELPHI的后期版本中还专门为TDataSet设计了一个虚函数CreateBlobStream,让不同类型的DataSet自己实现具体流。
你改成这样试试:
......
ClientDataSet1.CommandText := 'select * from atable';
ClientDataSet1.Open;
ClientDataSet1.Append;
aStream := ClientDataSet1.CreateBlobStream('aBlobFieldName', bmReadWrite);
aStream.CopyFrom(aFileStream, 0);
...... 这些代码只是示范,有错当查!李战.深圳
文件大小相同吗?
我用tdataset.fieldby('bb1').asblob.loadfromstream(fp)存,没使用过这种方法存。
你读文件的代码拿出来看看
cds.Edit;
TBlobField(Cds.FindField('blob')).LoadFrom(MyMemoryStream);
cds.Post;
cds.ApplyUpdate;
procedure TForm1.Button3Click(Sender: TObject);
var
stmFiles:Tfilestream;
strFileName:String;
begin
strFileName:='c:\write.doc';
stmFiles:=Tfilestream.Create(strFileName,fmOpenRead);
try
clientdataset1.CommandText:='insert into userid.xt_blob(YHDM,YHMC,YHKL,QM)'+' values(''vts'',''笑眯眯'',''111'',:BB1)';//QM是一个BLOB字段类型.
clientdataset1.Params.CreateParam(ftblob,'BB1',ptInput);
clientdataset1.Params.ParamByName('BB1').LoadFromStream(stmFiles,ftblob);
clientdataset1.Execute;
clientdataset1.Params.Clear;
finally
stmfiles.Free;
end;
end;
注意:
1.数据库的字段大小大于该文件的大小好几倍,所以不存在字段容量不够大的问题
2. 提交的是一个SQL的方法来插入,而不是要用什么Append,Post之类的方法来实现.
3. 本人测试过,用TQuery插入的方法插入后,又用TQuery将其文件读出,一切都正常.但是我用TQuery插入的word文档,用TClientDataSet读出是正常的,所以证明我读出的代码没有任何问题.而用TClientDataSet插入的记录,再用TClientDataSet或TQuery读出后的文件却比原文件小了点,所以文件读出的是坏的,说明用TClientDataSet写入时的文件就不正确了.
4.本人用的TSocketConnection连接,应用服务器端的BDE的BlobSize也设置的正确.所以该问题也排除.
5.但是如果插入的文件是一个txt文件类型时,一切都正确.
6.该问题也等到了一些网友的解答,但是经本人测试,好像也没有作用,也许是本人愚笨,写的不正确,所以烦请各为高手能给出一个完整的,经过测试过的方法,多谢大家的支持,问题一但解决,本人就散分!
本程序的读出代码如下(是正确的):
procedure TForm1.Button2Click(Sender: TObject);
var
stmFiles:Tfilestream;
strFileName:String;
begin
strFileName:='c:\read.doc';
if FileExists(strFileName) then
deletefile(strFileName);
stmFiles:=Tfilestream.Create(strFileName,fmCreate);
try
clientdataset1.CommandText:='select * from userid.xt_blob where yhdm=''vts'''; clientdataset1.Open;
clientdataset1.Last;
clientdataset1.First;
if clientdataset1.RecordCount >0 then
begin
TBlobField(clientdataset1.FieldByName('QM')).SaveToStream(stmFiles);
end;
finally
stmfiles.Free;
end;网友回答例子:
好像用DataSet的参数将BLOB字段的值传递给SQL只对BDE有效,对ClientDataSet或ADO是有问题的。
所以,ClientDataSet或ADODataSet一般都是通过建立其BLOB字段的流对象来实现流操作。TClientDataSet可建立TClientBlobStream类型的流,TADODataSet可建立TADOBlobStream类型的流。
在DELPHI的后期版本中还专门为TDataSet设计了一个虚函数CreateBlobStream,让不同类型的DataSet自己实现具体流。
你改成这样试试:
......
ClientDataSet1.CommandText := 'select * from atable';
ClientDataSet1.Open;
ClientDataSet1.Append;
aStream := ClientDataSet1.CreateBlobStream('aBlobFieldName', bmReadWrite);
aStream.CopyFrom(aFileStream, 0);
...... 这些代码只是示范,有错当查!李战.深圳
文件大小相同吗?
我用tdataset.fieldby('bb1').asblob.loadfromstream(fp)存,没使用过这种方法存。
你读文件的代码拿出来看看
cds.Edit;
TBlobField(Cds.FindField('blob')).LoadFrom(MyMemoryStream);
cds.Post;
cds.ApplyUpdate;
解决方案 »
- 『我的Delphi用不成了,各位大侠有没有遇到这样的情况,请帮我出谋划策。急啊~!』
- 谁研究过程序的在线升级呢?欢迎大家来讨论一下
- 请教delphi局域网中上传图片实现
- 高分相赠,抢分啊,在线等-----关于delphi 的dll的调用
- 多维常量数组定义
- 以前我在CSDN看过类似的贴字,现在忘了这样的sql语句怎么写,请知情者赐教!!
- 请madeinchina看看,也欢迎大家看看
- 特急!!!,称心请教高手---delphi的web应用问题
- 原来系统是access做的,现在要改成sql的,不知道有没有高手指点一下?请你留下QQ,行不?
- 在Dbgrid控件中某一列为数字,如果为“0”,如何让其显示为空白?
- 高分求救:怎样实现QQ聊天软件中的聊天记录按钮下面ListBox控件?????
- dgGrid 或 stringGrid 标题列能不能折行显示文字????
function TDMF1Client.LoadFormat(F1book: TF1book): boolean;
begin
result := true;
with cdsFormat do
begin
Active := false;
CommandText := 'select * from XT_FB_YSB where rtrim(FORMATCODE)=''' + FormatInfo.FormatCode + '''';
try
active := true;
except
result := false;
showmessage('从数据库读取格式失败。');
end;
end;
end;procedure TfrmInterface.WriteFormatToCds(F1book: TF1book);
var
sTempFile: string;
begin
sTempFile := getSysTempPath + '\' + nTempFileName;
f1book.Write(sTempFile, F1FileFormulaOne6);
with DMF1Client do begin
cdsFormat.first;
if not cdsFormat.eof then
begin
cdsFormat.edit;
cdsFormat.FieldByName('FORMATNAME').AsString := FormatInfo.FormatName;
cdsFormat.FieldByName('FORMATKEY').AsString := FormatInfo.FormatKey;
cdsFormat.FieldByName('FORMATTYPE').AsString := FormatInfo.FormatType;
cdsFormat.FieldByName('CALLERFRAME').AsString := FormatInfo.CallerFrame;
end
else
begin
cdsFormat.insert;
end;
cdsFormat.FieldByName('FORMATCODE').AsString := FormatInfo.FormatCode;
cdsFormat.FieldByName('FORMATNAME').AsString := FormatInfo.FormatName; cdsFormat.FieldByName('FORMATKEY').AsString := FormatInfo.FormatKey_inFormatTable;
cdsFormat.FieldByName('FORMATTYPE').AsString := FormatInfo.FormatType;
cdsFormat.FieldByName('CALLERFRAME').AsString := FormatInfo.CallerFrame;
cdsFormat.FieldByName('DATAAREA').AsString := FormatInfo.DataArea;
cdsFormat.FieldByName('CHARAREA').AsString := FormatInfo.CharArea;
cdsFormat.FieldByName('MEMOAREA').AsString := FormatInfo.MemoArea;
try cdsFormatFORMATCONTENT.LoadFromFile(sTempFile);//和数据库中BLOB字段对应的Field对象,
//定义为 cdsFormatFORMATCONTENT: TBlobField;
//在字段管理器里生成 cdsFormat.post;
deleteFile(pchar(sTempFile));
except
ShowMessage('保存格式出错');
end;
end;
end;function TDMF1Client.SaveFormat(F1book: TF1book): boolean;
var
sTempFile: string;
i: Integer;
begin
result := true;
with cdsFormat do begin
try i := cdsFormat.ApplyUpdates(0);
result := (i = 0);
except
ShowMessage('保存格式出错');
result := false;
end;
end;
scF1Format.Connected := false;end;
当时我上Borland看了,是个D5的Bug,没有办法,只能自己解决。
我是自己在appserver上加了个uploadpic的接口,然后将图片转换为olevariant类型来传送到Appserver,然后Appserver再从olevariant转换到Tmemorystream,在Appserver中插入数据库中。然后搞定。
原来的代码得找一找,不知道还在不在。
楼主用的是D5吗?
客户端 + socket + 中间层 + ado + sql server;
读出、写入借助stream。
写入:
var
ms:tmemorystream;
begin
ms:=TmemoryStream.Create;
ms.Loadfromfile(“1.jpg”);
if ms.size>0 then
begin
ms.position:=0;
(Clientdateste1.fieldbyname('dipicture') as Tblobfield).loadfromstream(ms);
end ;
end;读出:
var
ms:tstream;
myjpg:tjpegImage;
begin
ms:=clientdataset1.createblobstream(clientdataset1.fieldbyname('dipicture'),bmread);
if ms.size>0 then
begin
ms.position:=0;
myJpg:=tjpegimage.create;
myJpg.loadFromstream(ms);
Image1.Picture.assign(myjpg);//在Image1中显示出来
end;
end;
上面的代码绝对没错我测试过的。
我没有时间写更多了,希望这些有所帮助。