上传文件至数据库:invalid class typecast。MSSQL2005,BLOB类型?image类型?

WindowsX 2017-12-18 02:50:36
CSDN某个地方看到,这段代码可以上传文件(附件)至数据库保存。
但是运行时,提示 invalid class typecast
大约意思是,类型转换时失败(无效?)。
出错地方在这一句:
Stream := TBlobStream.Create(FieldByName('Documents') as TBlobField, bmWrite);
麻烦大家,应该做怎么样的修改?


procedure Tfrm_NetCRMAdd.btnOpenDocClick(Sender: TObject);
var
MemSize: integer;
Buffer: PChar;
Myfile: TFileStream;
Stream: TBlobStream;
begin
OpenDialog1.Filter :=
'文档(*.doc,*.docx,*.xls,*.xlsx,*.pdf)|*.doc;*.docx;*.xls;*.xlsx;*.pdf';
{ 从对话窗选择文件 } // ,*.docx,*.xls,*.xlsx,*.pdf
if OpenDialog1.Execute then
begin
Myfile := TFileStream.Create(OpenDialog1.FileName, fmOpenRead);
with aqNetCRM do { ‘aqNetCRM’为含BLOB字段的表名: TADOQuery }
begin
if Not(State in [DsEdit, DsInsert]) then
Edit;
Stream := TBlobStream.Create(FieldByName('Documents') as TBlobField,
bmWrite); { ‘Documents’为BLOB字段名,但是MSSQL没有BLOB类型,改为image类型 }
//在此提示错误:invalid class typecast
MemSize := Myfile.Size;
Inc(MemSize);
{ Make room for the buffer's null terminator. }
Buffer := AllocMem(MemSize); { Allocate the memory. }
try
Stream.Seek(0, soFromBeginning);
{ Seek 0 bytes from the stream's end point }
Myfile.Read(Buffer^, MemSize);
Stream.Write(Buffer^, MemSize);
finally
Myfile.Free;
Stream.Free;
end;

try
Post;
except
on E: EDatabaseError do
{
if HandelException(E) <>0 then
//HandelException(E) 提示未定义,注释这一段
exit
else
}
raise ;
end;

end;
Doc_Ole.CreateObjectFromFile(OpenDialog1.FileName, False);
Doc_Ole.Run; { Doc_ole为ToleContainer构件名 }
end;
end;
...全文
584 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
dg_glg 2020-03-07
  • 打赏
  • 举报
回复
太简单了,把字段类型设为 Image,我用是的Access数据库,其他数据库都差不多。 写入:TBlobField(adoQuery.FieldByName('fImage')).LoadFromFile('d:\测试1.doc'); 取出:TBlobField(adoQuery.FieldByName('fImage')).SaveToFile('d:\测试2.doc');
WindowsX 2017-12-23
  • 打赏
  • 举报
回复
引用 14 楼 DelphiGuy 的回复:
那需要你选取文档的时候检查一下文件大小,超过限制不向stream里写就可以了。
谢谢。
  • 打赏
  • 举报
回复
那需要你选取文档的时候检查一下文件大小,超过限制不向stream里写就可以了。
WindowsX 2017-12-22
  • 打赏
  • 举报
回复
引用 11 楼 DelphiGuy 的回复:
var Field: TBlobField; Stream: TBlobStream; //... Field := TBlobField(aqNetCRM.FieldByName('Documents')); Stream := TBlobStream(aqNetCRM.CreateBlobStream(Field, bmWrite));
大师,非常感谢。。成功了!。谢谢。 刚试了一下。一不小心把一个 15M 的 DOC 文档传进去了。 我厚着脸皮咧,还想请教,如何限制上传文档的大小?比如超过 2M 的文档,禁止上传。 在上面代码应该作怎么样的修改? 谢谢。
WindowsX 2017-12-21
  • 打赏
  • 举报
回复
引用 9 楼 DelphiGuy 的回复:
是编译时还是运行时?
编译通过。运行的时候出错。
日月路明 2017-12-21
  • 打赏
  • 举报
回复
我们一般这么处理: function T_FileData.GetBinHexData(FileName:string): string; var FS: TFileStream; s: string; s1: string; Size: Int64; begin FS:=TFileStream.Create(FileName,fmOpenRead); Size:=FS.Size; SetLength(s,Size); FS.Read(Pchar(s)^,Size); Fs.Free; SetLength(s1,2*Size+1); FillChar(Pchar(s1)^,2*Size+1,#0); BinToHex(pchar(s),pchar(s1),Size); Result:='0x'+s1; end; sql:='inert into Table(....FileData)seect.....FileData=‘+ GetBinHexData('c:\a.txt') ADoQuery.ExecSQL(sql) 就可以了
  • 打赏
  • 举报
回复
var Field: TBlobField; Stream: TBlobStream; //... Field := TBlobField(aqNetCRM.FieldByName('Documents')); Stream := TBlobStream(aqNetCRM.CreateBlobStream(Field, bmWrite));
WindowsX 2017-12-20
  • 打赏
  • 举报
回复
引用 5 楼 DelphiGuy 的回复:
TBlobField(FieldByName('Documents'))
大师,您是说,把这一句: Stream := TBlobStream.Create(FieldByName('Documents') as TBlobField, bmWrite); 改成这样: Stream := TBlobStream.Create(TBlobField(FieldByName('Documents')) as TBlobField, bmWrite); 也是不行。(MSSQL里面表的字段 Documents 已经改为 varbinary(MAX)) 这一句还是提示 invalid class typecast
WindowsX 2017-12-20
  • 打赏
  • 举报
回复
引用 7 楼 DelphiGuy 的回复:
我的意思是 Stream := TBlobStream.Create(TBlobField(FieldByName('Documents')), bmWrite);
大师,还是不行。还是这一句提示 invalid class typecast
  • 打赏
  • 举报
回复
是编译时还是运行时?
  • 打赏
  • 举报
回复
我的意思是 Stream := TBlobStream.Create(TBlobField(FieldByName('Documents')), bmWrite);
  • 打赏
  • 举报
回复
TBlobField(FieldByName('Documents'))
WindowsX 2017-12-19
  • 打赏
  • 举报
回复
引用 3 楼 DelphiGuy 的回复:
ms sql server是支持BLOB类型的,你吧对应字段类型改为VarBianry(max)
大师,还是原地方提示 invalid class typecast
  • 打赏
  • 举报
回复
ms sql server是支持BLOB类型的,你吧对应字段类型改为VarBianry(max)
WindowsX 2017-12-19
  • 打赏
  • 举报
回复
引用 1 楼 DelphiGuy 的回复:
Stream := TBlobStream.Create(FieldByName('Documents') as TBlobField, bmWrite); 这里的TBlobField可以用TGraphicField或者TVarBytesField试试
大师,改成 TGraphicField 后,还是这里提示 invalid class typecast 改成 TVarBytesField 后,编译不通过: E2010 Incompatible types: 'TBlobField' and 'TVarBytesField' 可还有其他办法没有呢? 我的需求这样:我只是有一张表,填写完其他内容后,添加一个附件,一起保存至数据库。
  • 打赏
  • 举报
回复
Stream := TBlobStream.Create(FieldByName('Documents') as TBlobField, bmWrite); 这里的TBlobField可以用TGraphicField或者TVarBytesField试试

2,497

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 数据库相关
社区管理员
  • 数据库相关社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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