我在做一个进销存软件时,把销售出库单使用dbgrideh做为录入窗口,录入完成后循环插入到数据库中,修改的时候先读出到dbgrideh中,修改保存时我是先把表中的原记录都删掉,再重新插入进去,但是效率很低,且遇到网络延时或不稳定时会造成数据丢失!请教有什么好的解决办法?

解决方案 »

  1.   

    最好的办法是Insert和Update,这样可以保证一次性成功。如果一定要先Delete,再Insert的话,就用数据库的事务来完成。
      

  2.   

    sanmaotuo(老冯)  你说得太专业了,能否说得具体点!
      

  3.   

    好吧,给个例子(是我的应用系统中的)  IVisitor = interface
      ['{B8931615-26B6-40F9-ACE2-5CFC28E9AA7D}']
        procedure Visit(const Visited: IInterface);
      end;  IVisited = interface
      ['{2F90DFBE-3B0B-4D4D-A66B-37B9C83CA96C}']
        procedure Accept(const Visitor: IVisitor);
      end;  ILine = interface(IVisited)
      ['{5A54B657-7EBC-4DCA-A0AA-E30413E621A3}']
        function GetLineID: string;
        procedure SetLineID(const Value: string);
        function GetLineName: string;
        procedure SetLineName(const Value: string);
        property LineID: string read GetLineID write SetLineID;
        property LineName: string read GetLineName write SetLineName;
      end;  TDBVisitor = class(TInterfacedObject, IVisitor)
      private
        FConnection: TADOConnection;
        FQuery: TADOQuery;
      protected
        property Connection: TADOConnection read FConnection;
        property Query: TADOQuery read FQuery;
        //IVisitor
        procedure Visit(const Visited: IInterface); virtual; abstract;
      public
        constructor Create; reintroduce; virtual;
        destructor Destroy; override;
      end;  TLineInsertVisitor = class(TDBVisitor)
      private
      protected
        //IVisitor
        procedure Visit(const Visited: IInterface); override;
      public
      end;  TLineUpdateVisitor = class(TDBVisitor)
      private
      protected
        //IVisitor
        procedure Visit(const Visited: IInterface); override;
      public
      end;  ....下面是GUI录入后(新增或修改)  FBO: ILine;  procedure TBasicLineEditFrame.MapFromBO;
      begin
        EdtLineID.Text := FBO.LineID;
        EdtLineName.Text := FBO.LineName;
      end;  procedure TBasicLineEditFrame.MapToBO;
      begin
        FBO.LineID := EdtLineID.Text;
        FBO.LineName := EdtLineName.Text;
      end;  新增:
      var
        Visitor: IVisitor;
      begin
      ......
        Visitor := TLineInsertVisitor.Create;
          try
            FBO.Accept(Visitor);
            Application.MessageBox(PChar('新增线路['+FBO.LineName+']成功'), MCaption, 64);
            ResetControl;
          except
            on E:ELineIDExisted do Application.MessageBox(PChar('线路编号['+FBO.LineID+']重复'), MCaption, 64);
            on E:EDBException do Application.MessageBox(PChar('新增线路['+FBO.LineName+']失败'), MCaption, 64);
          end;    修改:
        Visitor := TLineUpdateVisitor.Create;
          try
            FBO.Accept(Visitor);
            Application.MessageBox(PChar('编辑线路['+FBO.LineName+']成功'), MCaption, 64);
            AcCancel.Execute;
          except
            on E:EDBException do Application.MessageBox(PChar('编辑线路['+FBO.LineName+']失败'), MCaption, 64);
          end;
      

  4.   

    sanmaotuo(老冯)-----------------------------------------------------------
    Delphi的语法,Java的设计思路,不错!
      

  5.   

    skypeople(飞飞)
    --------------------
    能否给一个用CLINETDATASET来实现的例子啊?感谢老冯.你真的很强!
      

  6.   

    本来就应该像老冯那样做。用对象保存RECORD的数据,然后用GRID显示就OK了。