先问一句,url和urltime是什么类型的!

解决方案 »

  1.   

    都是CString
    数组也是,我使用多线程对sUrl数组进行处理的,可是处理完毕后似乎记录和表更新有问题
    #define MAX_ADDR 50000
    #define MAX_THREADS 20
    CString sAddress[MAX_ADDR];
    bool    bAssigned[MAX_ADDR];
    bool    bFinished[MAX_ADDR];
    CString sTime[MAX_ADDR];
    int nSites;
    int nTasks;
    int nThreads;
    CCriticalSection cs;
    // ***************
    // *             *
    // *  VisitSite  *
    // *             *
    // ***************
    // Description: Thread routine to visit sitesUINT VisitSite(LPVOID pParam)
    {
    CRobotInternet internet;
    int nResult;
    CString sHeader, sModified,sErrMsg;
    int nTask; while(nTasks > 0) // While there is work to do,从后往前来,nTasks由大变小
    {
    // Find a site to process
    nTask = -1;
    cs.Lock();
    for (int t = 0; t < nSites; t++)
    {
    if (!bAssigned[t])
    {
    bAssigned[t] = true;
    nTask = t;
    t = nSites;
    } // End if
    } // End for
    cs.Unlock();
    /* If there are no more sites to process, 
       shut down this thread */
    if (nTask == -1)
    {
    cs.Lock();
    nThreads--;
    cs.Unlock();
    return 0;
    } // end if
    // Attempting to read a header from the site
    if (internet.httpHeaderFields(sAddress[nTask],
    sHeader,
    nResult,
    sErrMsg))
    {
    internet.httpGetHeaderField("last-modified",sModified);
                if(sModified=="")
    {
        cs.Lock();
                    sTime[nTask]="N/A";             
        cs.Unlock();
    }
    else
    {
    cs.Lock();
                    sTime[nTask]=sModified;             
        cs.Unlock();
    }
               
    } // End if
    else
    {
                cs.Lock();
                sTime[nTask]=sErrMsg;             
    cs.Unlock();
    }
    // Mark site as finished and decrement task count
    cs.Lock();
    bFinished[nTask] = true;
    nTasks--;
    cs.Unlock();
    } // End while
    cs.Lock();
    nThreads--;
    cs.Unlock();
    return 0;
    }
    void CMTimeDlg::OnDbQueryOK() 
    {
    // TODO: Add your control notification handler code here
        HRESULT hr=S_OK;
    hr=m_ptrRs.CreateInstance(__uuidof(Recordset));
    if(FAILED(hr))
    _com_issue_error(hr);
        GetDlgItemText(IDC_SQL,m_strCmdText);
    hr=m_ptrRs->Open((LPCTSTR)m_strCmdText,(LPCTSTR)m_strConnectString,
    adOpenKeyset,adLockOptimistic,adCmdText);
    if(FAILED(hr))
    _com_issue_error(hr);

    if(m_ptrRs->adoEOF)
    {
    AfxMessageBox("没有匹配的记录!",MB_OKCANCEL);
    m_ptrRs->Close();
    return;
    }

    long nRecordCount=0;//记录数
    //int nTimes=0;
    while(!m_ptrRs->adoEOF)//计算记录数
    {
    nRecordCount++;
    m_ptrRs->MoveNext();
    }
    m_ptrRs->MoveFirst();
        
    /* if(nRecordCount%MAX_ADDR==0)//计算页数
    {
    nTimes=int(nRecordCount/MAX_ADDR);
    }
    else
    {
    nTimes=int(nRecordCount/MAX_ADDR)+1;
        }*/ _bstr_t bstrFieldName0=m_ptrRs->Fields->GetItem((long)0)->GetName();
        CString strFieldName=_com_util::ConvertBSTRToString(bstrFieldName0);// for(int i=0;i<nTimes;i++)
    // {
    for(long i=0;i<MAX_ADDR;i++)//将sAddress[]和sTime[]全部置空
    {
    sAddress[i]="";
    sTime[i]="";
    }
        //    m_nPage=i;
            //_bstr_t bstrFieldName=m_ptrRs->Fields->GetItem((long)0)->GetName();
            //CString strFieldName=_com_util::ConvertBSTRToString(bstrFieldName);    while(!m_ptrRs->adoEOF)
    {    
     /*for(long k=0;k<MAX_ADDR;k++)
     {
         if(m_ptrRs->adoEOF)
    {
    break;
    }
    else
    {*/
    for(long j=0;j<nRecordCount;j++)//将记录值赋给sAddress[]数组
    {
        _variant_t varFieldName;
                _variant_t varFieldValue;
        char* pName=strFieldName.GetBuffer(strFieldName.GetLength());
            varFieldName.SetString(pName);
            varFieldValue=m_ptrRs->GetCollect(varFieldName);
        varFieldValue.ChangeType(VT_BSTR);
        sAddress[j]=varFieldValue.bstrVal;
        m_ptrRs->MoveNext();

    }
    } nSites=0;
    nTasks=0;
    while(nSites<nRecordCount)//初始化bAssigned[]和bFinished[]数组
    {
    bAssigned[nSites]=FALSE; 
    bFinished[nSites]=FALSE;
    nSites++;//都为nRecordCount大小
    nTasks++;//当nTasks=0时,程序结束
    } nThreads=0;//正在运行的线程数
    for(int n=0;n<MAX_THREADS;n++)//启动线程,20个
    {
    AfxBeginThread(VisitSite,NULL);
    nThreads++;
    }    SetTimer(1,1000,NULL);
    m_ptrRs->MoveFirst();
    //写结果到数据库
        for(long k=0; k<nRecordCount; k++)
    {
    //_variant_t varRFieldName;
            _variant_t varRFieldValue;
        char* pTime=sTime[k].GetBuffer(sTime[k].GetLength());
    varRFieldValue=_com_util::ConvertStringToBSTR(pTime);
    m_ptrRs->PutCollect((long)1,varRFieldValue);
    //m_ptrRs->Update((long)1,varRFieldValue);
    m_ptrRs->MoveNext();
    }
        //更新记录,更新表 
        m_ptrRs->UpdateBatch(adAffectAll); 
    m_ptrRs->Close();
    //SetTimer(1,1000,NULL);
    }void CMTimeDlg::OnTimer(UINT nIDEvent) 
    {
    // TODO: Add your message handler code here and/or call default
    KillTimer(1);
    if(nTasks>0||nThreads>0)
    {
    m_sStatus.Format("剩余URL数:%d,活动线程数:%d",nTasks,nThreads);
    UpdateData(FALSE);
    SetTimer(1,1000,NULL);
    }
    else
    {
    m_sStatus="完成";
    GetDlgItem(IDOK)->EnableWindow(TRUE);
    UpdateData(FALSE);
    }
    }
      

  2.   

    我建议你看一下机械工业出版社的<<Visual C++6.0 数据库开发技术>>的最后一章用ADO开发数据库应用程序。
    象返回的记录数可以用m_ptrRs->RecordCount这个属性来获得。
    然后对应每一条记录可以用一个类来处理。
    #import "c:\program files\common files\system\ado\msado15.dll"  rename_namespace("ADOCG") rename("EOF", "EndOfFile")
    using namespace ADOCG;
    #include <icrsint.h>class CDataRecord:public CADORecordBinding
    {
    BEGIN_ADO_BINDING(CDataRecord)
    ADO_VARIABLE_LENGTH_ENTRY4(1,adVarChar,re_id,sizeof(re_id),TRUE)
    ADO__LENGTH_ENTRY2(2,adInteger,xx,TRUE) END_ADO_BINDING()
    public:
    BYTE  re_id[21];          //对应数据库中的字段       varchar(20)
             int xx                    //对应数据库中的字段       int 
    };
    具体实现可以用下面的一段代码:void GetRecord()
    {
    char szQuery[2048];
    _bstr_t strResult;
        CoInitialize(NULL);

    _ConnectionPtr m_pConnection;//先声明变量
    _CommandPtr m_pCommand;
    _RecordsetPtr m_rst;
    _RecordsetPtr m_rstNew;
    IADORecordBinding *m_piAdoRecordBinding;
    CDataRecord *m_rsRecSet;
    m_rsRecSet=new CDataRecord;
    HRESULT hr;//开始初始化变量
    long lRecordCount; 
        _bstr_t strQry;
    char pcConnect[800];
    try{
    hr=m_pConnection.CreateInstance(__uuidof(Connection));
    if(SUCCEEDED(hr))
    {
    strcpy(pcConnect,"provider=Microsoft.Jet.OLEDB.4.0;Data Source=c:\\test.MDB;");
    _bstr_t strConnect(pcConnect);
    hr=m_pConnection->Open(strConnect,
    _bstr_t(L"Admin"),
    _bstr_t(L""),
    adModeUnknown);//连接数据库
    if(FAILED(hr))
    {
    MessageBox(NULL,"数据库连接失败!","错误",MB_OK|MB_ICONSTOP);
    return;
    }
    }else return;
    m_rst.CreateInstance(__uuidof(Recordset));
    char szQueryNew[1000];
    strcpy(szQuery, "SELECT * fROM tbl_yqj");
    strcpy(szQueryNew,"insert into mytest values(\"11\",16)");
    strQry=(_bstr_t)szQuery;
    m_rst->Open(strQry, _variant_t((IDispatch*)m_pConnection, true),
    adOpenKeyset, adLockOptimistic, adCmdText);
    lRecordCount = m_rst->RecordCount;
    if(lRecordCount<=0)
    {
    m_pConnection->Close();
    MessageBox(NULL,"没有相应的数据!","错误",MB_OK|MB_ICONSTOP);
    return;
    }
    m_piAdoRecordBinding=NULL;
    m_rst->QueryInterface(_uuidof(IADORecordBinding),(LPVOID *)&m_piAdoRecordBinding);
    if(!m_piAdoRecordBinding) 
    {
    m_rst->Close();
    m_pConnection->Close();
    MessageBox(NULL,"没有查询到端口","错误",MB_OK|MB_ICONSTOP);
    return;
    }
    m_piAdoRecordBinding->BindToRecordset(m_rsRecSet);
    m_rst->PageSize=10;
    m_rst->AbsolutePage=(PositionEnum)1;
    for(int i=0;i<m_rst->PageSize;i++)
    {
    sprintf(szQuery,"%s",m_rsRecSet->re_id);
    AfxMessageBox(szQuery);
    sprintf(szQuery,"%d",m_rsRecSet->xx);
    AfxMessageBox(szQuery);
    m_rst->MoveNext();
    if (m_rst->EndOfFile) break;
    }
    m_rst->Close();
    }catch(_com_error &e)
    {
    PrintComError(e);
    }

    }void PrintComError(_com_error &e)
    {
       _bstr_t bstrSource(e.Source());
       _bstr_t bstrDescription(e.Description());    // Print Com errors.
       printf("Error\n");
       printf("\tCode = %08lx\n", e.Error());
       printf("\tCode meaning = %s\n", e.ErrorMessage());
       printf("\tSource = %s\n", (LPCSTR) bstrSource);
       printf("\tDescription = %s\n", (LPCSTR) bstrDescription);
    }这样你将获得的记录数据转入你的数组中去,然后再对应的进行修改,修改完之后再用
         m_piAdoRecordBinding->Update(m_rsRecSet);进行更新,但首先要定位到该条记录然后修改m_rsRecSet的内容,再执行上面的一句。m_piAdoRecordBinding->AddNew(m_rsRecSet);可用来增加记录,增加完后要移动一下,切记,否则加不进去的,如m_rst->MoveNext();你还是看一下那本书吧。
      

  3.   

    那个类应该是这样的。少加了一个FIXED
    class CDataRecord:public CADORecordBinding
    {
    BEGIN_ADO_BINDING(CDataRecord)
    ADO_VARIABLE_LENGTH_ENTRY4(1,adVarChar,re_id,sizeof(re_id),TRUE)
    ADO_FIXED_LENGTH_ENTRY2(2,adInteger,xx,TRUE)END_ADO_BINDING()
    public:
    BYTE  re_id[21];          //对应数据库中的字段      varchar(20)
            int xx                    //对应数据库中的字段      int 
    };
      

  4.   

    to liouyun(四海任逍遥):我想请你看看,我上面的代码,看看能否实现我的意图,或者稍加修改也可以。你的方法我觉得不太适合我的程序?