问题:
   我要往数据库添加上千条记录,顺序是先从库1取出然后依次添到库2、库3中,为什么添加过程中突然莫名其妙出错!而此时查看数据库可以看到只添到了几十条,并且库2、库3中不一样多,真是搞不懂我是同时对他们进行添加的,怎么会两者添加的不一样多。
  还有个疑问:我重复运行几次,每次出错时添加的数目都不一样,这次添加30来条出错,下次也需是70来条  声明:单步调试没出错,当然我没有调试完,因不可能等他一条一条地加上1000来条。

解决方案 »

  1.   

    试试,不同时添加;先往库2添加,执行完后;再往库3添加;
    多使用try ...catch以避免数据库
    连接意外中断;
    每100条commit一次;
      

  2.   

    nbgyf(梅花峰) :能不能在说明白一些!
                 每100条commit一次;是什么意思
    另外:先往库2添加,执行完后;再往库3添加;速度太慢
      

  3.   

    出错时提示什么信息?nbgyf的意思是启用事务,具体是:
    BeginTrans,CommitTrans,RollbackTrans,可以看看MSDN。
    事务可以回滚,可以有限度的保证操作成功,楼主可以试试。
      

  4.   

    我估计是错误处理没作完的问题。我们自己的做程序也会碰到这样的情况,ADO读写数据库的纪录的时候,如果这个纪录为空的话,这是很容易出问题的。
    我建议你,在读和写的时候,所有字段添加一些如果为空的处理代码。
      

  5.   

    声明:
        错误提示:
               代码:80040e21
               含义:IDispatch error #3105
               描述:无法更新:当前被锁定
      

  6.   

    sxtigerVC(tiger) :
      你说的字段不同,我觉得不应该是这个问题,我是用不同记录对象recordset打开的,跟字段有何关系。
      

  7.   

    而且你最好还要检查你的SQL语句
      

  8.   

    #3105 16 Data on dump will not fit into current database. Need %ld Mbyte database. 我觉得是数据类型不匹配,也就是说写入数据库的数据与数据库中定义的类型不匹配,所以出错。
    也可能是该项不能为空,而你写入了空。
    不确定,我以前遇到过这样的问题。
      

  9.   

    好像是数据库被Lock掉了;
    楼上的这些兄弟说的有点道理;
    也可能其它的程序也正在更新或者修改该表(或者open的参数有问题);
    你会其它语言吗?
    如PB、Dephi、Java、VB什么用它试试会不会成功;如果数据量很大就不行了;不过你可以使用存储过程让sql直接在Server上执行,就少了数据
    在C<--->S的传递时间
      

  10.   

    可能是由于数据类型不匹配引起的,不敢肯定
    “含义:IDispatch error #3105
      描述:无法更新:当前被锁定

    含义和描述你是怎么得来的,是错误的提示吗?
    能不能看看你那段代码?
      

  11.   

    catch(_com_error e)///捕捉异常
    {
    CString errormessage;
    _bstr_t bstrSource(e.Source());
    _bstr_t bstrDescription(e.Description());
    errormessage.Format("代码:%08lx\n含义:%s\n描述:%s\n",e.Error(),e.ErrorMessage(),
    (LPCSTR)bstrDescription);
    AfxMessageBox(errormessage);
    }
      

  12.   

    贴这个还不如将数据库读取和写入那一段呢,我也很想看看到底是什么问题如果不方便,可以将你的那一段代码拷贝,mail给我,[email protected]我帮你看看
      

  13.   

    下面是原代码,其中DataGet2是一个自定义类,是用来访问数据库的类。
    while(!DataGet2.m_pRecordset->adoEOF)
    {   /////取出数据/////
    vUser = DataGet2.m_pRecordset->GetCollect("操作人");
    vDate = DataGet2.m_pRecordset->GetCollect("测试时间");
    vType = DataGet2.m_pRecordset->GetCollect("弹簧片型号");

    strType=(LPCTSTR)(_bstr_t)vType;
    if(strType.Right(2)=="UP")
    {

    length=strType.GetLength();
    vType=strType.Left(length-3);
    vUpDown="上";
    UDSign="上";
    }
    else if(strType.Right(4)=="DOWN")
    {
    length=strType.GetLength();
    vType=strType.Left(length-5);
    vUpDown="下";
    UDSign="下";
    }

    vxyK=DataGet2.m_pRecordset->GetCollect("K坐标");
    vxyF=DataGet2.m_pRecordset->GetCollect("F坐标");

    /////修正k值、f值///////

    stringType=(LPCTSTR)(_bstr_t)vType;
    if(UDSign=="上")
    strText.Format("select * from 分选板分档参数表 where 弹簧片型号='%s' and 上下片='上'",stringType);
    else if(UDSign=="下")
    strText.Format("select * from 分选板分档参数表 where 弹簧片型号='%s' and 上下片='下'",stringType);
    else
    strText.Format("select * from 分选板分档参数表 where 弹簧片型号='%s'",stringType);
    DataGet6.OpenRecordset("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=弹簧片分档.mdb",strText);
    if(!DataGet6.m_pRecordset->adoEOF)
    {

    vTemp=DataGet6.m_pRecordset->GetCollect("K值");
    fK=vTemp.fltVal;
    vTemp=DataGet6.m_pRecordset->GetCollect("F值");
    fF=vTemp.fltVal;
    vTemp=DataGet6.m_pRecordset->GetCollect("F值间隔");
    fFSpace=vTemp.fltVal;
    vTemp=DataGet6.m_pRecordset->GetCollect("K值间隔");
    fKSpace=vTemp.fltVal;
    fK=fK+(vxyK.lVal-5.5)*fKSpace;
    fF=fF+(vxyF.lVal-10.5)*fFSpace;
    vK=(float)fK;
    vF=(float)fF;
    }
    else
    {
    MessageBox("弹簧片分档库中无此型号!");
    break;
    }
    DataGet6.m_pRecordset->Close();//关闭弹簧片分档库
    /////添加数据到现存库中/////
    DataGet.m_pRecordset->AddNew();
    m_nCurrentSel = m_list.InsertItem(0xffff,"");
    SaveData();///保存数据

    ////同时添加数据到历史库中////
    DataGet1.m_pRecordset->AddNew();
    DataGet1.m_pRecordset->PutCollect("弹簧片型号",vType);
    DataGet1.m_pRecordset->PutCollect("测试时间",vDate);
    DataGet1.m_pRecordset->PutCollect("操作人",vUser);
    DataGet1.m_pRecordset->PutCollect("K值",vK);
    DataGet1.m_pRecordset->PutCollect("F值",vF);
    DataGet1.m_pRecordset->PutCollect("K坐标",vxyK);
    DataGet1.m_pRecordset->PutCollect("F坐标",vxyF);
    if(vUpDown.vt!=VT_NULL)
    DataGet1.m_pRecordset->PutCollect("上/下片",vUpDown);
    DataGet1.m_pRecordset->Update();
    ////测试记录下移//////

    DataGet2.m_pRecordset->MoveNext();

    }//END while
      

  14.   

    其实程序里面的事务应该和数据库里面的是一样的在SQL里面begin tran//就是开始事务
    commit tran//事务提交
    rollback tran //事务会滚事务是 这样的简单的例子就是银行转帐,从这个户头取出钱到那个户头存入钱
    应该是一个整体的过程
     如果在这个户头取出钱的时候,出现了异常,也就是说转帐还没有8完成,那么
    取出的钱就应该还给那个户头,如果没有事务的机制,这个钱就没有了
    这个是不合理的,所以在数据库里面可以把这些连贯的动作作为一个事务,只要有一个动作失败,整个操作都应该回到原始的
    状态,如果确定每个动作都成功,那么就像数据库提交刚才那些操作
    如果你用SQL SERVER数据库你可以在查询分析器里面这样做
    BEGIN TRAN
    INSERT TO XXXXX
    ……
    UPDATE XXXX
    ………
    然后
    你可以用SELECT XXXX
    看看结果是否对了,如果对了
    你就COMMIT TRAN
    如果错了你就ROLLBACK TRAN
    而且在你COMMIT或者是ROLLBACK前,刚才那些数据别人是看不到的
      

  15.   

    再看代码,顺便catch _com_err不一定能捕捉到所有异常
      

  16.   

    在实际的使用过程中一般的ADOCONNECTION里面已经封装了事务的处理
    你可以调用里面的方法,也可以直接用SQL算法大概是这样的
    BEGIN TRAN
    TRY
    ^^^^^^^
    COMMIT
    CATCH
    ROLLBACK
    END
      

  17.   

    SaveData();///当前类的保存?看到代码里似乎有两个地方都保存数据,发生异常时,错误在哪一句?DataGet6.OpenRecordset("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=弹簧片分档.mdb",strText);
    不知DataGet6的游标类型以及锁定类型是什么?(不过既然有部分数据保存成功,也许问题不在这)
      

  18.   

    在告诉大家一个异常,今天上午大概11左右我连续运行好几次都成功了,但在中午来后有突然出错!看看是否与时间有关!
    在搜索库1时我是根据时间来查找的
    COleDateTime m_date;
    string = m_date.Format("%m-%d-%y");
    sql.Format("select * from 测试记录 where 测试时间>=#%s 00:00:00# and 测试时间<=#%s 23:59:00#",string,string);
      

  19.   

    已经给你mail,希望对你有用。我记得access的时间应该是“年-月-日 时:分:秒”这样排列的吧,你怎么格式化成“月-日-年 时:分:秒”也没问题啊,这就奇怪了,真的。
    另外,字符串在select语句中是放在##中还是''中,我记得好像应该是''中阿。
      

  20.   

    事务具体怎么用,下面几句分别在什么时候用,是不是每操作一个数据库就要加入下面几句。
    pConnection->BeginTrans();
    pConnection->CommitTrans();
    pConnection->RollbackTrans();
    pConnection->Close();
      

  21.   

    通俗的说一个连接可以对应多个事务,每个事务可以对应不同的操作;pConnection->BeginTrans();.........if (sucess) 
        pConnection->CommitTrans();
    else
        pConnection->RollbackTrans();
    pConnection->Close();
      

  22.   

    应该都是差不多的不过我坚持认为这些程序你至少应该把SQL语句弄出来到数据库里面看看如果是SQL SERVER,就是查询分析器ACCESS的化,里面有个查询,你新建查询就可以了
      

  23.   

    Connection1->BeginTrans();
    try
    {
    for(i....)
    {
       Recordset->AddNew();
       Recorset...设置各个字段
       。。
    }
    Connect1->CommitTrans();}
    catch(_com_error& e)
    {
       Connection1.RollbackTrans();
       ...
    }如果提供者支持批更新,可以使提供者将多个记录的更改存入缓存,然后使用 UpdateBatch 方法在单个调用中将它们传送给数据库。这种情况应用于使用 AddNew、Update 和 Delete 方法所做的更改。调用 UpdateBatch 方法后,可以使用 Status 属性检查任何数据冲突并加以解决。
      

  24.   

    你是从程序中直接使用AddNew()来添加数据的吧?直接使用Addnew来添加数据是很危险的做法,简单的说:如果你的记录中有两条同样的数据,Addnew就无法帮你
    完成第二个数据添加 等等;如果你想要多添加的话,你最好使用调用存储过程的方式来添加数据我建议你写存储过程来添加数据;有必要在库1中使用一个触发器
      

  25.   

    qhluo02(*QHcsnd02) :
    1。使用调用存储过程的方式来添加数据,什么意思
    2。在库1中使用一个触发器,又是什么意思
      

  26.   

    1.就是在程序中读取你在SQL里所建立的存储过程
    2.这你的程序不至于使用
      

  27.   

    你说是用不同的记录对象进行操作,难怪出现分派出错的问题
    因为数据库每次操作都要判断其中断状态,对于数据倒动你完成一个接着完成另一个,对速度影响不是很大,只用也记录集recordset就行
      

  28.   

    问个问题:
      .....
      while(!m_pRecordset1->adoEOF)//////打开m_pRecordset1所连接的表1
      {////添加记录到m_pRecordset2所连接的表2
        m_pRecordset2->AddNew();
         .....
        m_pRecordset2->Update();
       ///添加记录到m_pRecordset3所连接的表3
       m_pRecordset3->AddNew();
         .....
        m_pRecordset3->Update();
      m_pRecordset1->MoveNext();
       }
    和下面的代码有什么区别
    while(!m_pRecordset1->adoEOF)//////打开m_pRecordset1所连接的表1
      {////添加记录到m_pRecordset2所连接的表2
        m_pRecordset2->AddNew();
         .....
        m_pRecordset2->Update();
       m_pRecordset1->MoveNext();
       }
       m_pRecordset1->MoveFirst();
    while(!m_pRecordset1->adoEOF)//////打开m_pRecordset1所连接的表1
      {////
    ///添加记录到m_pRecordset3所连接的表3
       m_pRecordset3->AddNew();
         .....
        m_pRecordset3->Update();
    m_pRecordset1->MoveNext();
    }
      

  29.   

    区别在:
    第二种方案m_pRecordset1的记录遍数了两次
      

  30.   

    DataGet.m_pRecordset->AddNew();
    m_nCurrentSel = m_list.InsertItem(0xffff,"");
    SaveData();///保存数据
    DataGet.m_pRecordset->AddNew();//只有addnew 没有update,是不是在savedata()中?程序这样看不出问题,数据类型与数据表中字段类型是否一一对应,你的程序中没有,我也没有认真看,想找出问题,还是要跟踪,你可以将各表的关键安显示出来,看看是那条记录出问题?是读出还是写入?是不是总是一条记录出问题?还是不同的记录出问题,这些都有是很重要的,光靠上面的程序很难看出问题。
    从你上面贴出的这两段代码我认为是一样的,第一种错误,第二种正确可能是因为其他程序出错,这跟踪出错到底在什么地方?
      

  31.   

    savedata()中有update我真不明白是什么问题,只要我分开操作就正确。
      

  32.   

    AddNew()会对RS“加锁”(不确切的词),我不确定会不会对此RS的Connection也做了保护,如果是这样的话,那么间隔太短,应该会有冲突吧。
    楼主可以试试不用Recordset而改用Command,直接Excute一个Insert的SQL,不知道会不会适合楼主的情况?希望楼主成功。
      

  33.   

    插入别用putCollect(),直接用sql语言写插入语句Insert into......
    这样效率比putCollect提高多了。
      

  34.   

    我都是过了,用insert into也不行