ADOQuery代替ClientDataSet做3-Tier系统
2005-09-06 13:41:00
3-Tier的系统我们一般用Midas的TClientDataSet,它搭配BDE的TQuery效率还可以,毕竟是一家的;但搭配TADOQuery就慢了很多,大概9倍,因为不晓得人家的资料存储格式,只能一个Field一个Field读出来再用TDataSetProvider打包成Data:OLEVariant;
ADO2.5提供了一个_Stream组件,配合BatchUpdate,可以做到TClientDataSet的功能,它的效率可以达到与TClientDataSet+TQuery一样:
1.Client给SQL到Server,Server用TADOQuery获取资料,然后Save到_Stream,返回;
2.Client用_Stream接收Server返回资料,给TADOQuery,用户可以随意增/删/改;
3.Client把用户修改后的资料Save到_Stream,传给Server(我现在还没办法只把异动资料存到_Stream,它把没有修改的资料也Save进去了,因为在WAN上跑时资料量对效率影响大;一种方法是存为XML格式,再用XML DOM组件去解析,把没修改的资料删掉,看各位还有更好的方法没有?);
4.Server用_Stream接收Client的修改资料,给TADOQuery,把FilterGroup设为fgPendingRecords,可以分析资料的增/删/改情况,处理企业逻辑,最后调用UpdateBatch保存资料。
5.Client在Call Server保存成功后,也调用UpdateBatch,使资料与实际一致,因为TADOQuery没有联接Connection,因此UpdateBatch相当于TClientDataSet的ClearChangeLog 
Server端的代码(Com+):
 
function TEOStudent.ReadADOData(const ASQL: WideString): OLEVariant;
var
  AStream:_Stream;
  MS1:TMemoryStream;
  V:OLEVariant;
  P:Pointer;
begin
  try
    ADOConnection.Close;
    ADOQuery.Close;
    ADOQuery.SQL.Text:=ASQL;
    ADOQuery.Open;
    AStream:=CoStream.Create;
    OLEVariant(ADOQuery.Recordset).Save(AStream,adPersistADTG);
    ADOQuery.Close;
    AStream.Position:=0;
    V:=AStream.Read(AStream.Size);
    MS1:=TMemoryStream.Create;
    try
      P:=VarArrayLock(V);
      try
        MS1.Size:=VarArrayHighBound(V,1)+1;
        Move(P^,MS1.Memory^,MS1.Size);
      finally
        VarArrayUnLock(V);
      end;
      Result:=VarArrayCreate([0,MS1.Size-1],varByte);
      P:=VarArrayLock(Result);
      try
        Move(MS1.Memory^,P^,MS1.Size);
      finally
        VarArrayUnLock(Result);
      end;
    finally
      MS1.Free;
    end;
    SetComplete;
  except
    SetAbort;
    Raise;
  end;
end;
 
procedure TEOStudent.SaveADOData(AData: OLEVariant);
var
  AStream:_Stream;
  AR:_Recordset;
begin
  try
    ADOQuery.Close;
    AStream:=CoStream.Create;
    AStream.Open(EmptyParam,adModeUnknown,adOpenStreamUnspecified, ‘‘, ‘‘);
    AStream.Type_:=adTypeBinary;
    AStream.Write(AData);
    AStream.Position:=0;
    AR:=_Recordset(CoRecordset.Create);
    AStream.Position:=0;
    AR.Open(AStream,EmptyParam,adOpenKeyset,adLockBatchOptimistic,0);
    ADOConnection.Close;
    ADOConnection.Open;
    AR.Set_ActiveConnection(ADOConnection.ConnectionObject);
    ADOQuery.Recordset:=ADOInt._Recordset(AR);
{    ADOQuery.FilterGroup:=fgPendingRecords;
    ADOQuery.Filtered:=true;
    try
      ADOQuery.First;
      while not ADOQuery.Eof do
      begin
        case ADOQuery.UpdateStatus of
          usModified:ShowMessage(
  VarToStr(ADOQuery.FieldByName(‘SeqNo‘).OldValue)+‘:‘+
  ADOQuery.FieldByName(‘SeqNo‘).asString);
        end;
        ADOQuery.Next;
      end;
    finally
      ADOQuery.Filtered:=false; //stateless
    end;}
    ADOQuery.UpdateBatch;
    ADOConnection.Close;
    SetComplete;
  except
    SetAbort;
    Raise;
  end;
end;

Client端,Form上放一个TADOQuery,不用连接Connection:
 
获取资料
procedure TForm1.Button5Click(Sender: TObject);
var
  V:OLEVariant;
  AR:_Recordset;
  AStream:_Stream;
  MS1:TMemoryStream;
  P:Pointer;
  s:string;
begin
  DCOM.Connected:=true;
  try
    s:=‘‘;
    V:=DCOM.AppServer.ReadADOData(‘select * from FORMDD‘);
    MS1:=TMemoryStream.Create;
    try
      MS1.Size:=VarArrayHighBound(V,1)+1;
      P:=VarArrayLock(V);
      try
        Move(P^,MS1.Memory^,MS1.Size);
      finally
        VarArrayUnLock(V);
      end;
      V:=VarArrayCreate([0,MS1.Size-1],varByte);
      P:=VarArrayLock(V);
      try
        Move(MS1.Memory^,P^,MS1.Size);
      finally
        VarArrayUnLock(V);
      end;
    finally
      MS1.Free;
    end;
    AStream:=CoStream.Create;
    AStream.Open(EmptyParam,adModeUnknown,adOpenStreamUnspecified, ‘‘, ‘‘);
    AStream.Type_:=adTypeBinary;
    AStream.Write(V);
 
    AR:=_Recordset(CoRecordset.Create);
    AStream.Position:=0;
    AR.Open(AStream,EmptyParam,adOpenUnspecified, adLockUnspecified, -1);
    ADOQuery1.Recordset:=ADOInt._Recordset(AR);
  finally
    DCOM.Connected:=false;
  end;
end;
 
//保存资料
procedure TForm1.Button6Click(Sender: TObject);
var
  AStream:_Stream;
  V:OLEVariant;
begin
  DCOM.Connected:=true;
  try
    ADOQuery1.CheckBrowseMode;
    AStream:=CoStream.Create;
    OLEVariant(ADOQuery1.Recordset).Save(AStream,adPersistADTG);
    AStream.Position:=0;
    V:=AStream.Read(AStream.Size);
    DCOM.AppServer.SaveADOData(V);
    ADOQuery1.UpdateBatch;  //no connection,means clearchangelog
  finally
    DCOM.Connected:=false;
  end;
end;

转载于:https://www.cnblogs.com/fuyingke/archive/2005/10/14/254669.html

ADOQuery代替ClientDataSet做3-Tier系统相关推荐

  1. SAP MM MIGO移动类型311试图做批次确定,系统报错-Stock Determination or batch determination not possible-

    SAP MM MIGO移动类型311试图做批次确定,系统报错-Stock Determination or batch determination not possible- SAP系统里的批次确定功 ...

  2. SAP QA32 做使用决策系统报错:分类数据的不一致性=交易终止

    SAP QA32 做使用决策系统报错:分类数据的不一致性=>交易终止 QA32,对如下检验批做处理,系统报错, 试图使用MSC3N去显示这个批次主数据,同样报错, 原因在于批次的分类数据产生后, ...

  3. 内容社区,为什么有必要做内容标签系统?

    社区内容量很大时,内容曝光有限,非常影响社区作者创作的积极性.为了解决内容曝光有限的问题,内容标签系统不失为一种有效的解决方案.本文结合一些案例来探讨,做内容标签系统的必要性. 一.问题背景 社区产品 ...

  4. 我想做一个课程表系统利用PHP+MYSQL+HTML实现课表的展示,但是不知道如何实现

    我想做一个课程表系统利用PHP+MYSQL+HTML实现课表的展示,但是不知道如何实现 1.课表不是唯一一个课表. 2.通过录入的课表信息展示在HTML表格 想实现的效果如图: 收藏 (1) 分享 举 ...

  5. python车牌识别系统开源代码_天津谁做车牌识别系统供应商,伸缩栅栏门_郑州荣锋科技有限公司...

    首页 > 新闻中心 发布时间:2020-11-13 22:54:57 导读:郑州荣锋科技有限公司为您提供天津谁做车牌识别系统供应商,伸缩栅栏门的相关知识与详情: (1)门处于关闭状态,控制器应骆 ...

  6. 天云服务器做系统,自己做云服务器系统

    自己做云服务器系统 内容精选 换一换 监控是保持云耀云服务器可靠性.可用性和性能的重要部分,通过监控,用户可以观察云耀云服务器资源.为使用户更好地掌握自己的云耀云服务器运行状态,公有云平台提供了云监控 ...

  7. 网校系统开发如何做才能保证系统稳定发展

    疫情的出现,加速了在线教育的发展.尤其是在教育领域本就资源不平等的环境中,在线教育的出现,无疑是改善了教育领域存在的弊端.网校系统开发商也紧紧抓住机会,开发出不同版本的网校系统,供有所需求的用户使用. ...

  8. 5.2.4 js循环小练习02 6 做学院评奖系统​ 如果数学成绩大于80分并且语文成绩大于80分,获奖学金500元。​如果数学小于30并且语文小于30分,输出重修。 两个数a、b,如果a能被b整除

    文章目录 1 做学院评奖系统​ 如果数学成绩大于80分并且语文成绩大于80分,获奖学金500元.​ 如果数学小于30并且语文小于30分,输出重修. 2 两个数a.b,如果a能被b整除或a加b大于100 ...

  9. 骷髅峡谷,转苹果网卡做黑苹果macOS系统还是装WIFI6网卡ax200?

    骷髅峡谷,转苹果网卡做黑苹果macOS系统还是装WIFI6网卡ax200? 翻看骷髅峡谷主板正反面,看到可以diy的资源只有2个NVME固态盘接口. 已经是有不少玩家使用以下的这款转卡转接苹果网卡去黑 ...

最新文章

  1. 算法炒房三月亏20多亿!房地产巨头大翻车:房价水太深,AI根本把握不住
  2. java write_java中write(byte[] b)与write(byte[] b,int off,int len)区别
  3. 通向未来:物联网+人工智能将成为人类的进化方向
  4. struts2的bean类名首字母和第二个字母都不能大写
  5. 专访阿里云MVP王俊杰:开发者的超能力是用技术让世界更美好
  6. QT中动态库和静态库使用
  7. sqlserver 2008安装总是弹出重启提示
  8. 变位齿轮重合度计算公式_齿轮“模数”是如何计算的?
  9. php 查看扩展 代码,[扩展推荐] 使用 PHP Insights 在终端查看 PHP 项目代码质量
  10. ESXI 6.7安装并部署主机
  11. python re正则_正则表达式+Python re模块详解
  12. 智能问答系统方法综述
  13. dnsmasq安装配置
  14. 计算机网络的创新创业计划书,互联网创新创业计划书.doc
  15. Symantec Endpoint Protection(SEP) 离线病毒库下载与升级
  16. 利用 UPnP 的反射攻击分析
  17. 附件的文件夹超过了服务器,邮件附件太大发不了 这3种方式了解一下
  18. redis哨兵模式出现connected_slaves:0解决办法
  19. Integer、new Integer()和int的区分与比较
  20. 虽然计算机应用的范围越来越广,下列各句中,加点的成语使用恰当的一项是( ) A.虽然计算机应用的范围越来越广,但拥有了它并不意味着一切工作都会那么轻而易举,一挥而就。 B... _满分5_满分网...

热门文章

  1. Deep Learning-论文翻译以及笔记
  2. volatile关键字到底做了什么?
  3. 基于mcat开发以太坊智能合约
  4. TensorFlow-CIFAR10 CNN代码分析
  5. Android面试题详细整理系列(一)
  6. JZOJ 3693. 【NOI2014模拟6.20】慎二的随机数列
  7. JZOJ 3804. 【NOIP2014模拟8.24】小X 的AK 计划
  8. linux虚拟内存当硬盘,linux里面虚拟内存和swap有什么不同?
  9. android联网程序,android 联网 HttpClient
  10. php lucene索引,用PHP调用Lucene包来实现全文检索_PHP教程