大家好:
有一个表A,里面有f1和f2两个字段,该表中有一条记录.
现在要通过VC++编程用update语句将一段经过加密了的字符串写到表的这两个字段中,由于加密了的字符串中很可能包含字符串结束标志,因此用普通的update语句难以实现更新功能,于是有一位朋友帮我写了段代码,但执行后总是报告异常,现贴出代码,请知道的朋友指导错在哪里了,代码调用的是一个别人写好了的ADO封装类:adocmd.SetCommandText(("update A set f1='@a',f2='@b' adocmd.CreateParameter(_T("@a"),ADODB::adVarBinary,ADODB::adParamInput,137,passkey1);
adocmd.CreateParameter(_T("@b"),ADODB::adVarBinary,ADODB::adParamInput,137,passkey2);
adocmd.Execute(ADODB::adCmdText);跟踪了一下,发现调用CreateParameter的时候就报告了一个不太清楚的异常了,请达人指导或者提供一个解决类似问题的方法!

解决方案 »

  1.   

    屏幕太短第一句没贴全:
    adocmd.SetCommandText(("update A set f1='@a',f2='@b'));
      

  2.   

    adocmd.SetCommandText(("update A set f1=@a,f2=@b));
      

  3.   

    参数f1和参数f2都是varchar 255类型,经过简单的跟踪,目前只是发现在CreateParameter语句执行的时候就产生了异常!
      

  4.   

    写成 adocmd.SetCommandText(("update A set f1=@a,f2=@b)); 似乎也不行
      

  5.   

    passkey1的类型定义入下:
    BYTE passkey1[255];
    memset(passkey1,0,sizeof(passkey1));
    然后用一个产生密码的函数向passkey1中产生了一个值的!
      

  6.   

    if(FAILED(::CoInitialize(NULL))) 
    return; 
    try
    {
    _ConnectionPtr  pConn  = NULL ;
    _RecordsetPtr  pRs  = NULL ;
    _RecordsetPtr  pRs2  = NULL ;
    _CommandPtr comm = NULL ;
    _ParameterPtr param =NULL ;
    ParametersPtr params=NULL; HRESULT  hr = S_OK; _bstr_t strCnn("Driver={SQL Server};Server=(local);Uid=sa;Pwd=p6lx+;DataBase=test"); pConn.CreateInstance(__uuidof(Connection));
    pConn->CursorLocation =adUseClient;
    pConn->ConnectionTimeout =60;
    pConn->Open (_bstr_t(strCnn),_bstr_t(""),_bstr_t(""),adModeUnknown); comm.CreateInstance(__uuidof(Command));
    param.CreateInstance(__uuidof(Parameter)); //pRs.CreateInstance(__uuidof(Recordset)); comm->ActiveConnection=pConn;
    comm->CommandType=adCmdStoredProc; BYTE bytes[200];
    BYTE * pbytes=bytes;
    memset(bytes,'\0',sizeof(bytes));
    VARIANT     varBLOB;   
    SAFEARRAY   *psa;   
    SAFEARRAYBOUND   rgsabound[1];   
    if(pbytes)   
    {           
    rgsabound[0].lLbound   =   0;   
    rgsabound[0].cElements   =   200;   
    psa   =   SafeArrayCreate(VT_UI1, 1, rgsabound);                                             ///创建SAFEARRAY对象   
    for   (long i = 0; i < (long)200; i++)   
    SafeArrayPutElement   (psa, &i,pbytes++);                                                   ///将pBuf指向的二进制数据保存到SAFEARRAY对象psa中   
    varBLOB.vt   =   VT_ARRAY   |   VT_UI1;                                                                       ///将varBLOB的类型设置为BYTE类型的数组   
    varBLOB.parray   =   psa;                                                                                           ///为varBLOB变量赋值   

    }     
    param = comm->CreateParameter ("@bbb",adVarBinary,adParamInput,255,varBLOB);
    comm->Parameters->Append(param);
    param = comm->CreateParameter ("@t",adVarChar,adParamInput,50,_variant_t("test"));
    comm->Parameters->Append(param);
    params=comm->Parameters;
    TRACE("%d\n",params->Count);
    comm->CommandText="sp_bin"; comm->Execute(NULL,NULL,adCmdStoredProc);
    if (pRs)
    if (pRs->State == adStateOpen)
    pRs->Close();
    if (pRs2)
    if (pRs2->State == adStateOpen)
    pRs2->Close();
    if (pConn)
    if (pConn->State == adStateOpen)
    pConn->Close();
    }
    catch (_com_error pCome)
    {
    TRACE("Error info: %s \n", (LPCTSTR)(_bstr_t)(pCome.Description()));
    TRACE("Error info: %s \n", (pCome.ErrorMessage()));}
    ::CoUninitialize();
    ----------------------------------------
    你的代码有些问题,command一般调用带参数的存储过程,调用带参数的sql语句可能有问题,所以写一个存储过程最保险
    BYTE字节的数据要保存到为安全数组才能赋值,不能直接那样用
    如果一定要用sql语句,要把BYTE数组转换为16进制的字符串表示比如0x0000000000这样,0x写在最前面。然后构造sql语句update A set f1=0x00000...,f2=0xaaaaa...这样就可以
      

  7.   

    //下面这个版本可以直接使用带参数的sql 语句
    if(FAILED(::CoInitialize(NULL))) 
    return; 
    try
    {
    _ConnectionPtr  pConn  = NULL ;
    _RecordsetPtr  pRs  = NULL ;
    _RecordsetPtr  pRs2  = NULL ;
    _CommandPtr comm = NULL ;
    _ParameterPtr param =NULL ;
    ParametersPtr params=NULL; HRESULT  hr = S_OK; //_bstr_t strCnn("Driver={SQL Server};Server=(local);Uid=sa;Pwd=p6lx+;DataBase=test");
    _bstr_t strCnn("Provider=SQLOLEDB.1;Password=p6lx+;Persist Security Info=True;User ID=sa;Initial Catalog=test;Data Source=(local)"); pConn.CreateInstance(__uuidof(Connection));
    pConn->CursorLocation =adUseClient;
    pConn->ConnectionTimeout =60;
    pConn->Open (_bstr_t(strCnn),_bstr_t(""),_bstr_t(""),adModeUnknown); comm.CreateInstance(__uuidof(Command));
    param.CreateInstance(__uuidof(Parameter)); //pRs.CreateInstance(__uuidof(Recordset)); comm->ActiveConnection=pConn;
    comm->CommandType=adCmdStoredProc; BYTE bytes[200];
    BYTE * pbytes=bytes;
    memset(bytes,'C',sizeof(bytes));
    VARIANT     varBLOB;   
    SAFEARRAY   *psa;   
    SAFEARRAYBOUND   rgsabound[1];   
    if(pbytes)   
    {           
    rgsabound[0].lLbound   =   0;   
    rgsabound[0].cElements   =   200;   
    psa   =   SafeArrayCreate(VT_UI1, 1, rgsabound);                                             ///创建SAFEARRAY对象   
    for   (long i = 0; i < (long)200; i++)   
    SafeArrayPutElement   (psa, &i,pbytes++);                                                   ///将pBuf指向的二进制数据保存到SAFEARRAY对象psa中   
    varBLOB.vt   =   VT_ARRAY   |   VT_UI1;                                                                       ///将varBLOB的类型设置为BYTE类型的数组   
    varBLOB.parray   =   psa;                                                                                           ///为varBLOB变量赋值   

    }     
    param = comm->CreateParameter ("@bbb",adVarBinary,adParamInput,255,varBLOB);
    comm->Parameters->Append(param);
    param = comm->CreateParameter ("@t",adVarChar,adParamInput,50,_variant_t("funck"));
    comm->Parameters->Append(param);
    params=comm->Parameters;
    TRACE("%d\n",params->Count);
    //注意观察这里
    comm->CommandText="update bin set bbb=?,t=?";
    comm->Execute(NULL,NULL,adCmdText);
    if (pRs)
    if (pRs->State == adStateOpen)
    pRs->Close();
    if (pRs2)
    if (pRs2->State == adStateOpen)
    pRs2->Close();
    if (pConn)
    if (pConn->State == adStateOpen)
    pConn->Close();
    }
    catch (_com_error pCome)
    {
    TRACE("Error info: %s \n", (LPCTSTR)(_bstr_t)(pCome.Description()));
    TRACE("Error info: %s \n", (pCome.ErrorMessage()));}
    ::CoUninitialize();