if (EXECUTE_ADO_OK == pDB->Execute(szCommand))
{
bOk = TRUE;
}else
{
memset(szCommand,0,sizeof(szCommand));
sprintf_s(szCommand, sizeof(szCommand), INSERT_PLAYERINFO,m_szTableName, m_playerID,m_leagueID,szDate,m_tKills,m_tDeath,m_tRound,m_ctKills,
m_ctDeaths,m_ctRound,m_kills,m_deaths,m_misplayer,m_);
if (EXECUTE_ADO_FALSE == pDB->Execute(szCommand))
{
WriteLog("CPlayerKill", "SaveProc failed");
bOk = FALSE;
}
else  
{
bOk = TRUE;
}
}
upDate语句,同insert语句是正确的,但是就是会出现重复键的错误,我是采用多线程处理,写数据库的时候都会加锁,  重复键的问题是有时会出现 ??????????????????

解决方案 »

  1.   

    主键是什么?你是如何在你的程序中生成这个值的?你目前是通过什么机制来确保主键不重复?如果是 select max(id) +1 这种方式,当然会有重复。建议使用自增字段 auto_increment.
      

  2.   

    我的写入数据库的数据是从网络接收而来,在我每次要做插入的时候,我都会先做一次UpDate操作,当Update不成功的时候,我才做插入操作,这样的话应该能保证,主键唯一
      

  3.   

    主键是id,同日期if (0 >= m_playerID || NULL == pDB || TimeType < TABLETIME_DAY || TimeType > TABLETIME_YEAR ) 
    {
    return FALSE;
    }
    BOOL bOk = FALSE;
    char szCommand[MAX_COMMANDELEN] = {0};
    char m_szTableName[MAX_NAMELEN] = {0};
    BOOL bUpdate = FALSE;
    char szWeek[MAX_TIMELEN] = {0}; TableTail(m_logDate.wYear,m_logDate.wMonth,m_logDate.wDay,szWeek,sizeof(szWeek));
    sprintf_s(m_szTableName,sizeof(m_szTableName),"leaguememberinfo_%s",szWeek); char szDate[MAX_TIMELEN] = {0};
    sprintf_s(szDate,sizeof(szDate),"%d-%02d-%02d",m_logDate.wYear,m_logDate.wMonth,m_logDate.wDay);
    sprintf_s(szCommand, sizeof(szCommand), "UPDATE %s SET ", m_szTableName);
    if(type == 1)//T
    {
    /*更新TKills*/
    if (m_tKills != 0)
    {
    sprintf_s(szCommand, sizeof(szCommand), "%s TKills = TKills + %d,",
    szCommand,m_tKills);
    bUpdate = TRUE;
    } /*更新TDeaths*/
    if (m_tDeath > 0)
    {
    sprintf_s(szCommand, sizeof(szCommand), "%s TDeaths = TDeaths + %d,",
    szCommand,m_tDeath);
    bUpdate = TRUE;
    }
    /*更新TRounds*/
    if (m_tRound > 0)
    {
    sprintf_s(szCommand, sizeof(szCommand), "%s TRounds = TRounds + %d,",
    szCommand,m_tRound);
    bUpdate = TRUE;
    }

    else if(type == 2)//CT
    {
    /*更新CTKills*/
    if (m_ctKills != 0)
    {
    sprintf_s(szCommand, sizeof(szCommand), "%s CTKills = CTKills + %d,",
    szCommand,m_ctKills);
    bUpdate = TRUE;
    }
    /*更新CTDeaths*/
    if (m_ctDeaths > 0)
    {
    sprintf_s(szCommand, sizeof(szCommand), "%s CTDeaths = CTDeaths +  %d,",
    szCommand,m_ctDeaths);
    bUpdate = TRUE;
    }
    /*更新CTRounds*/
    if (m_ctRound > 0)
    {
    sprintf_s(szCommand, sizeof(szCommand), "%s CTRounds = CTRounds + %d,",
    szCommand,m_ctRound);
    bUpdate = TRUE;
    }
    }
    /*更新Kills*/
    if (m_kills !=  0)
    {
    sprintf_s(szCommand, sizeof(szCommand), "%s Kills = Kills + %d,",
    szCommand,m_kills);
    bUpdate = TRUE;
    }
    /*更新Deaths*/
    if (m_deaths > 0)
    {
    sprintf_s(szCommand, sizeof(szCommand), "%s Deaths = Deaths + %d,",
    szCommand,m_deaths);
    bUpdate = TRUE;
    }
    /*更新MissTimes*/
    if (m_misplayer > 0)
    {
    sprintf_s(szCommand, sizeof(szCommand), "%s MissTimes = MissTimes + %d,",
    szCommand,m_misplayer);
    bUpdate = TRUE;
    }
    /*更新Mark*/
    if (m_ != 0)
    {
    sprintf_s(szCommand, sizeof(szCommand), "%s Mark = Mark + %d,",
    szCommand,m_);
    bUpdate = TRUE;
    }
    /*更新LeagueID*/
    if (m_leagueID > 0)//可能会发生转社团的情况
    {
    sprintf_s(szCommand, sizeof(szCommand), "%s LeagueID = %d,",
    szCommand,m_leagueID);
    bUpdate = TRUE;
    }
    int iComLen = strlen(szCommand);
    szCommand[iComLen - 1] = 0;
    sprintf_s(szCommand, sizeof(szCommand), "%s WHERE PlayerID = %d AND logDate = '%s'", szCommand, m_playerID, szDate); if(bUpdate)
    {
    if(TimeType == TABLETIME_DAY)
    {
    if (EXECUTE_ADO_OK == pDB->Execute(szCommand))
    {
    bOk = TRUE;
    }else
    {
    memset(szCommand,0,sizeof(szCommand));
    sprintf_s(szCommand, sizeof(szCommand), INSERT_PLAYERINFO,m_szTableName, m_playerID,m_leagueID,szDate,m_tKills,m_tDeath,m_tRound,m_ctKills,
    m_ctDeaths,m_ctRound,m_kills,m_deaths,m_misplayer,m_);
    if (EXECUTE_ADO_FALSE == pDB->Execute(szCommand))
    {
    WriteLog("CPlayerKill", "SaveProc failed");
    bOk = FALSE;
    }
    else  
    {
    bOk = TRUE;
    }
    }
    }
    }
    return bOk;
    }
      

  4.   

    unsigned short CADODatabase::Execute(LPCTSTR lpstrExec)
    {
    ASSERT(m_pConnection != NULL);
    ASSERT(strcmp(lpstrExec, _T("")) != 0);
    _variant_t vRecords; m_nRecordsAffected = 0; try
    {
    m_pConnection->CursorLocation = adUseClient;
    m_pConnection->Execute(_bstr_t(lpstrExec), &vRecords, adExecuteNoRecords);
    m_nRecordsAffected = vRecords.iVal;
    if(m_nRecordsAffected != 0)//执行成功
    {
    return 1;
    }else//执行失败
    {
    return 2;
    }
    }
    catch(_com_error& e)//异常
    {
            WriteLog("ado2_exception", lpstrExec);
    _bstr_t description = e.Description();
    WriteLog("ado2_exception",description);
    return 3;
    }
    }
      

  5.   

    在上面的代码前,都会有pDB->Lock
      

  6.   


    唯一键自增长就行了,为什么还要--“先做一次UpDate操作,当Update不成功的时候,我才做插入操作”?
      

  7.   

     代码太长了。
    能否用SQL语句来说明你的算法。主键 是 (ID,日期)先 update, 
       update .... where  的时候 主键是什么?如何得到的?update 不成功,则 insert .. values (.. ) 此时 主键是什么? 关键是你产生主键的机制是什么?
      

  8.   

    也就是ID会重复?ID是日期型、自增字段?
    如果不是自增字段,可以用一张表存放ID,用户取数,锁表,执行完UPDATE、INSERT后更新ID值,
    取消锁表
      

  9.   

    主键并不能用自增长的方式来确定,数据是来自网络,另外数据库要做的更多的操作就是Update
      

  10.   

    首先,接收网络数据
        以接收到的网络数据,更新数据记录
    当更新失败的时候,插入数据记录  
    我的数据库表 原来是空的,接收网络数据,对playerID的行为分天来记录
      

  11.   

    主键 是 (ID,日期) 先 update, 
      update .... where  的时候 主键是什么?如何得到的? update 不成功,则 insert .. values (.. ) 此时 主键是什么? 关键是你产生主键的机制是什么?update .... where  的时候 主键是什么? (update 同 insert的主键都是,网络中接收到的 playerID,同本地日期)主键是网络中接收到的 playerID,同本地日期, 我要做的就是对playerID的行为进行统计,更新数据记录
      

  12.   

    就好比说 
        UPDATE  leaguelog_2009_month_12 SET kills=100 where leagueid=120;失败然后我    INSERT INTO leaguelog_2009_month_12(leagueid,kills)VALUES(120,100);然后就 Duplicate entry '1-2009-12-01 00:00:00' for key 1
        
      

  13.   

    (playerID,本地日期)应该是你没有锁表的原因。应该按这个序列进行操作
    lock tables xxx 
    update ..
    insert ..
    unlock tables;
      

  14.   

    CREATE TABLE `leaguelog_2009_month_12` (
      `LeagueID` int(11) default NULL,
      `Kill` int(11) default '0',
       PRIMARY KEY  (`LeagueID`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
    这是leaguelog_2009_month_12表 
      

  15.   

    本地日期应该改成服务器日期才严密按你说的,update 不成功,则 insert .. values (.. ),应该是可行的,怎么会有重复的?
      

  16.   

    10楼所述
    lock tables xxx 
    update  
    insert  
    unlock tables;OR
    专门用一张表存放主键,取出时锁表,执行update 、insert  ,再unlock
      

  17.   

    或者在MYSQL中你可以有更简便的方法insert into xxx ... on duplicate update col=col+1;语法这儿我就不贴了
     
    你自己到文档中查吧
    INSERT .. ON DUPLICATE
    REPLACEMySQL官方文档 http://dev.mysql.com/doc/refman/5.1/zh/index.html
      

  18.   

    在数据库操作的时候我都会有pDB->Lock();数据库操作pDB->UnLock()
      

  19.   

    在你的5,6楼的代码中没有看到你在什么地方做的 LOCK()也实在不想猜了。你是lock 
    update 
    unlock
    lock insert
    unlock 
    还是lock
    update
    insert 
    unlock ?加的锁是什么类型? S 还是 X ?
      

  20.   

    采用replace into代替insert into应该就可以了。
    replace into先查找更新,如果记录不存在就插入。