我在Win2000下用Delphi6+Access2000做了一个系统,采用BDE(5.2.02)联结数据库,可程序运行时有时经常出现以下错误:
1、Access Violation at address 005451E2 ,Read of address 005451E2
2、Access Violation at address 4BE06CB2 in module "IDAPI32.Dll".Read Of address 000000A8
3、有时点数据保存按钮时程序突然退出,而且是一点提示也没有,但数据却保存了。
开始我以为是BDE有问题,可重装后问题仍就;我以为BDE有BUG联结数据库有问题,可好多采用BDE的大型系统也没出现我这种情况。我用到的控件有1stClass3000vcl6、DevExpress QuantumGrid 4.1(D6)、XpMenu三种控件,不知与控件是不是有关系。
不知用BDE做系统的各位高手遇到过这种情况吗,我想改用ADO可不知能不能解决问题,还望各位高人指点一二,分数不够再加。

解决方案 »

  1.   

    呵呵,对,只有贴出源码才好分析呢!不过,好象不是BDE的错呢!
    我碰到过有些组件也会报这样的错,所以原因挺多的呢!
      

  2.   

    代码太多了,把数据保存函数的代码列出:
    function Tfrmygscdjb.datasave: Boolean; //数据保存函数
    var
      lsbl_djbh, lsbl_ydjbh, lsbl_bjzt, lsbl_date: string;
      lsbl_jlbh, lsbl_ID: Integer;
    begin
      try
      lsbl_bjzt := ygscdjb_bjzt;
      ygscdjb_bjzt := '';
      if lsbl_bjzt = 'Add' then
      begin
        lsbl_djbh := GetMaxdjbh();
        with ScdjmxbQuery do
        begin
          DisableControls;
          First;
          lsbl_jlbh := 0;
          while not Eof do
          begin
            lsbl_jlbh := lsbl_jlbh + 1;
            Edit;
            if FieldByName('scdj_cpybh').AsString <> '' then
            begin
              Edit;
              FieldByName('scdj_cpbh').AsString := Trim(FieldValues['scdj_cpybh']);
              FieldByName('scdj_djbh').AsString := lsbl_djbh;
              FieldByName('scdj_jlbh').AsString := Inttostr(lsbl_jlbh);
              Next;
            end
            else
              Delete;
          end;
          EnableControls;
          ApplyUpdates;
          CommitUpdates;
        end;
      end
      else
      begin
        lsbl_date := Trim(scndEdit.Text) + Trim(scrqEdit.Text);
        with scdjbTable do
        begin
          lsbl_ydjbh := FieldValues['scdj_djbh'];
          lsbl_djbh := Copy(lsbl_ydjbh, 1, 6);
          if lsbl_date <> lsbl_djbh then
          begin
            lsbl_djbh := GetMaxdjbh; //获取单据编号
          end;
          lsbl_djbh := FieldByName('scdj_djbh').AsString;
        end;
        with ScdjmxbQuery do
        begin
          DisableControls;
          First;
          lsbl_jlbh := 0;
          while not Eof do
          begin
            lsbl_jlbh := lsbl_jlbh + 1;
            if FieldByName('scdj_cpybh').AsString <> '' then
            begin
              lsbl_ID := FieldByName('ID').AsInteger;
              with PubProgFuncDataModule.CxQuery do
              begin
                Close;
                SQL.Clear;
                if ScdjmxbQuery.FieldByName('scdj_jlbh').AsInteger <> 0 then
                begin
                  SQL.Add('Update ygscdjmxb set scdj_djbh = :lsbl_djbh ,scdj_scrq = :lsbl_scrq ,');
                  SQL.Add('scdj_cpbh = :lsbl_cpbh ,scdj_cpybh = :lsbl_cpbh,scdj_gxbh = :lsbl_gxbh ,');
                  SQL.Add('scdj_xmbh = :lsbl_xmbh ,scdj_sl = :lsbl_sl,scdj_bz = :lsbl_bz ,');
                  SQL.Add('scdj_jlbh = :lsbl_jlbh ');
                  SQL.Add('where scdj_djbh = :lsbl_ydjbh and ID = :lsbl_ID');
                  ParamByName('lsbl_ydjbh').AsString := lsbl_ydjbh;
                  ParamByName('lsbl_ID').AsInteger := lsbl_ID;
                end
                else
                begin
                  SQL.Add('Insert into ygscdjmxb (scdj_djbh,scdj_scrq,scdj_cpbh,scdj_cpybh,');
                  SQL.Add('scdj_gxbh,scdj_xmbh,scdj_sl,scdj_bz,scdj_jlbh) values ');
                  SQL.Add('(:lsbl_djbh,:lsbl_scrq,:lsbl_cpbh,:lsbl_cpbh,:lsbl_gxbh,:lsbl_xmbh,');
                  SQL.Add(':lsbl_sl,:lsbl_bz,:lsbl_jlbh)');
                end;
                ParamByName('lsbl_djbh').AsString := lsbl_djbh;
                ParamByName('lsbl_scrq').AsDateTime := ScdjmxbQuery.FieldByName('scdj_scrq').AsDateTime;
                ParamByName('lsbl_cpbh').AsString := ScdjmxbQuery.FieldByName('scdj_cpybh').AsString;
                ParamByName('lsbl_gxbh').AsString := ScdjmxbQuery.FieldByName('scdj_gxbh').AsString;
                ParamByName('lsbl_xmbh').AsString := ScdjmxbQuery.FieldByName('scdj_xmbh').AsString;
                ParamByName('lsbl_sl').AsCurrency := ScdjmxbQuery.FieldByName('scdj_sl').AsCurrency;
                ParamByName('lsbl_bz').AsString := ScdjmxbQuery.FieldByName('scdj_bz').AsString;
                ParamByName('lsbl_jlbh').AsInteger := lsbl_jlbh;
                Prepare;
                ExecSQL;
                if ScdjmxbQuery.FieldByName('scdj_jlbh').AsInteger = 0 then
                begin
                  ScdjmxbQuery.Edit;
                  ScdjmxbQuery.FieldByName('scdj_jlbh').AsInteger := lsbl_jlbh;
                end;
              end;
            end
            else
              lsbl_jlbh := lsbl_jlbh - 1;
            Next;
          end;
          EnableControls;
        end;
      end;  with scdjbTable do
      begin
        Edit;
        FieldByName('scdj_djbh').AsString := lsbl_djbh;
        ApplyUpdates;
        CommitUpdates;
        if lsbl_bjzt = 'Edit' then
          Locate('scdj_djbh', lsbl_djbh, [loPartialKey]);
      end;
      with scdjmxbQuery do
      begin
        Close;
        ParamByName('lsbl_djbh').AsString := lsbl_djbh;
        PrePare;
        Open;
      end;
      Result := True;
      except
        if lsbl_jlbh = 1 then
          Messagebox(Self.handle, '保存【员工生产登记表】数据失败', '提示信息', mb_iconError + mb_Ok)
        else
          Messagebox(Self.handle, '保存【员工生产登记明细表】数据失败', '提示信息', mb_iconError + mb_Ok);
        scdjmxbQuery.EnableControls;
        Result := False;
      end;
    end;这段代码是数据保存函数,数据表分主从表,scdjbtable为主表联接的是一个实体表、scdjmxbQuery为从表联接的是一个视图,对主从表都采用缓存模式,本来如果数据改变进行数据保存时对主从表都使用ApplyUpdates、CommitUpdates,可是无论先保存哪个再保存另一个是时会提示"数据可能已被其他用户修改"的错误,但如果是新增数据则保存时不会出错;这样只好对"数据修改"时采用SQL语句进行保存。请大家看看这段代码,是不是有问题。可为什么有时候运行很正常,不知什么时候就出错。