关于在客户端利用TClientDataSet保存blob类型的字段问题

adventurezl 2003-04-03 05:45:13

创建一远程数据模块,添加组件并联接到一个数据库中,该数据库有一个大型二进制的字段(blob)FILE.客户端利用TClientDataSet进行更新,但是无法更新数据库,代码如下:
if (Edit2->Text.IsEmpty() )
return;
TMemoryStream *tmpStream = new TMemoryStream();
TBlobField *tmpField;
tmpStream->LoadFromFile(OpenDialog1->FileName);
client_DM->cdsFile_test->Close() ;
client_DM->cdsFile_test->Open() ;
client_DM->cdsFile_test->Edit();
client_DM->cdsFile_test->Append();
client_DM->cdsFile_test->Edit();
client_DM->cdsFile_test->FieldByName("ID")->AsString=Edit3->Text;
client_DM->cdsFile_test->FieldByName("NAME")->AsString=ExtractFileName(OpenDialog1->FileName);
tmpField = (TBlobField *)client_DM->cdsFile_test->FieldByName("FILE");
tmpField->LoadFromStream(tmpStream);
client_DM->cdsFile_test->Post() ;
client_DM->cdsFile_test->ApplyUpdates(-1);
tmpField = NULL;
delete tmpStream;

运行之后,只是在本地内存中修改,而无法保存到远程数据库中,请问原因何在?是不是ApplyUpdates函数不能保存blob类型的字段?
...全文
202 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
adventurezl 2003-04-11
  • 打赏
  • 举报
回复
问题终于解决了,多谢BCB(天下三分明月夜,二分无赖是扬州) ;马上结贴
BCB 2003-04-10
  • 打赏
  • 举报
回复
下面是我“人事档案”中的程序,我刚在三层DCOMConnection中试了完全成功!
.jpg或.bmp一律转换成.jpg存入字段,并能显示出!第二次打开,照片仍在!
再弄不明白就不应该了!

#include "jpeg.hpp"
void DispJpg() // 将字段中的.jpg图像--> Image1显示
{
TStream *bs=Form1->ClientDataSet1->CreateBlobStream(
Form1->ClientDataSet1->FieldByName("照片图像"),bmRead);
if(bs->Size>0)
{
TJPEGImage *j=new TJPEGImage;
bs->Position=0;
j->LoadFromStream(bs);
Form1->Image1->Picture->Bitmap->Assign(j);
delete j;
}
else
Form1->Image1->Picture=NULL;
delete bs;
}

void __fastcall TForm1::Button6Click(TObject *Sender)
{ // 将文件.bmp或.jpg以jpg 格式存入字段照片中
OpenDialog1->FileName="";
if (OpenDialog1->Execute())
{
String f=OpenDialog1->FileName;
if (FileExists(f))
{
String ext=ExtractFileExt(f).LowerCase();
if (ext==".bmp" || ext==".jpg"|| ext==".jpeg")
{
String jpg=ChangeFileExt(ExtractFileName(f),".jpg");
TJPEGImage *j=new TJPEGImage;
if (ext==".bmp")
{
Graphics::TBitmap *b=new Graphics::TBitmap;
b->LoadFromFile(f);
j->Assign(b);
j->CompressionQuality=90;
j->Compress();
delete b;
}
else
{
TFileStream *fs=new TFileStream(f,fmOpenRead);
j->LoadFromStream(fs);
delete fs;
}
ClientDataSet1->Edit();
TField *zd=ClientDataSet1->FieldByName("照片图像");
zd->Clear(); // 先清字段
TStream *bs=ClientDataSet1->CreateBlobStream(
zd,bmWrite);
bs->Position=0;
j->SaveToStream(bs);
delete j;
delete bs;
DispJpg();
}
}
}
}
//---------------------------------------------------------------------------

void __fastcall TForm1::Button7Click(TObject *Sender)
{
DispJpg();
}
void __fastcall TForm1::Button5Click(TObject *Sender)
{
if (ClientDataSet1->ChangeCount > 0)
ClientDataSet1->ApplyUpdates(-1); // 更新
ClientDataSet1->Close();

}
myy 2003-04-10
  • 打赏
  • 举报
回复
(回楼主短消息)

Sorry , 俺也不知道啊。。。
BCB 2003-04-10
  • 打赏
  • 举报
回复
Post()后再删,TBlobSream一定要用。
adventurezl 2003-04-10
  • 打赏
  • 举报
回复
楼上两位老大,还是不行啊!!to linlexing(拉拉叉) :你在post之前把ABlobStream 给delete了,那它被保存了么?我试了几次,程序在客户端是保存了,但是仍然没有提交到服务器端的数据库中。老大们,在想想办法。还有一个问题,就是保存时,为什么要用TBlobStream ?其它类型的Stream不行么?
BCB 2003-04-08
  • 打赏
  • 举报
回复
稍修改一下就成了
BCB 2003-04-08
  • 打赏
  • 举报
回复
你有两个错误:
1。没见你创建BlobStream;而只有TMemoryStream,
这是最大的错误!
TStream *tmpStream =DataSet1->CreateBlobStream(
zd,bmWrite);
2。流指针要重新回0;
tmpStream ->Position=0;
linlexing 2003-04-08
  • 打赏
  • 举报
回复
TBlobStream *ABlobStream = client_DM->CreateBlobStream(client_DM->cdsFile_test->FieldByName("FILE"),bmWrite) ;
ABlobStream->CopyFrom(tmpStream,0) ;
delete ABlobStream ; //一定要在Post之前删除
client_DM->cdsFile_test->Post() ;
client_DM->cdsFile_test->ApplyUpdates(-1);
tmpField = NULL;
delete tmpStream;
///以上的代码我用了N次了,包好
myy 2003-04-08
  • 打赏
  • 举报
回复
俺也不知道啊。。
adventurezl 2003-04-04
  • 打赏
  • 举报
回复
难道没人遇到过么?
winxp+delphi7+kbmmw4.0.3+unidac+mssql2000+dbgrideh 基本实现xalion中所说的功能并加上自己的一些编写经验 1、远程方法调用 2、取图像(流的使用) 3、查询数据 4、编辑数据:增、删、改(如果操作错误会进行相应的提示) 5、存储过程使用方法(存储过程参数自动创建) 6、动态创建数据集并执行Insert操作 7、命名查询(namedQuery) 8、事务操作(直接写SQL语句更新表的事务操作,有个重要的属性要设置,否则会更新不成功) 9、使用的数据库:sqlserver 2000,请到服务器的FDM单元把连接参数改下 10、数据库kbm_test结构参见:kbm_test.sql 11、安装kbmMw时请把配置文件 kbmMWConfig.inc中 {$DEFINE KBMMW_UNIDAC_SUPPORT} // UNIDAC support. 前面的//去掉 12、使用delphi7 2012年8月新增功能与说明 1、客户端断线重连:kbmMWTCPIPIndyClientTransport1.MaxRetries := 2;//重连一次 2、对象传输 3、JSON传输(利用kbmmw带的json库实现) 4、客户端断开代码: if FDM.kbmMWSimpleClient1.Transport.IsConnected then begin //memo1.Lines.Add('程序已有300秒没有进行操作,断开连接'); FDM.kbmMWSimpleClient1.Disconnect; end; 5、新增远程过程调用函数(直接SQL语句操作数据库): startTran:启动事务 commitTran:提交事务 rollbackTran:回滚事务 openSql:打开SQL语句 execSql:执行SQL语句 注openSql、execSql两个函数体代码使用对象连接池技术,无对象创建与释放,以提高系统效率, 具体能提高多少,未实测 6、增加HTTP协议例子(参考资料:kbmMW_and_AJAX.pdf),提供http-get的功能,http-post的功能可参照http-get方法实现 7、提供数据集转json与json转数据集 (CDSFromJSon(CDS:TClientDataSet;JsonStr:string):Boolean)单元:uDBJson.pas 参照代码可自行把json转kbmmwQuery kbmmw编译unidac方法: 修改单元kbmMWUNIDAC.pas,本人在数据库中很少用到blob字段,所以在代码里屏蔽掉blob字段的处理, 经测试数据库表字段类型为Text时,程序可以正常处理 报OLE DB error occured. CoInitialize has not been called (server)错误解决: unidac41src\Source\UniProviders\SQLServer\OLEDBAccessUni.pas constructor TOLEDBConnection.Create; begin inherited; CoInitialize(nil);//加此句 FCommand := nil; ... end; destructor TOLEDBConnection.Destroy; begin Disconnect; FCommand.Free; CoUninitialize;//加此句 inherited; end; 作者:chensm@vip.qq.com kbmmw开发交流群:209321818

1,317

社区成员

发帖
与我相关
我的任务
社区描述
C++ Builder 网络及通讯开发
社区管理员
  • 网络及通讯开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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