我使用VC.net 2005进行ADO编程访问sql server 2005,想使用存储过程插入记录,给存储过程的参数赋值时出错,不知道怎么解决,请高手指教。存储过程writeLog有三个参数,c_id char(1),s_id char(1),logtime datetime.C++的代码如下: _CommandPtr     pCmdWriteLog  = NULL;
_ParameterPtr    pPrmC_ID  = NULL;
_ParameterPtr    pPrmS_ID  = NULL;
_ParameterPtr    pPrmLogTime  = NULL;
VARIANT vtC_ID;
VARIANT vtS_ID;
VARIANT vtLogTime ;

        TESTHR(pCmdWriteLog.CreateInstance(__uuidof(Command)));
        pCmdWriteLog->ActiveConnection = pConnection;
        pCmdWriteLog->CommandText = "[dbo].[writeLog]";
pCmdWriteLog->CommandType = adCmdStoredProc;
        pCmdWriteLog->CommandTimeout = 15; vtC_ID.vt = VT_BYREF|VT_I1;
        vtC_ID.cVal  = strC_ID;
vtS_ID.vt = VT_BYREF|VT_I1;
        vtS_ID.cVal  = strS_ID;
vtLogTime.vt = VT_BYREF|VT_DATE;
SystemTimeToVariantTime(stLogTime,&vtLogTime.date); TESTHR(pPrmC_ID.CreateInstance(__uuidof(Parameter)));
pPrmC_ID->Type = adChar;
        pPrmC_ID->Size = 1;
        pPrmC_ID->Direction = adParamInput;
        pPrmC_ID->Value = vtC_ID;
        pCmdWriteLog->Parameters->Append(pPrmC_ID); TESTHR(pPrmS_ID.CreateInstance(__uuidof(Parameter)));
        pPrmS_ID->Type = adChar;
        pPrmS_ID->Size = 1;
        pPrmS_ID->Direction = adParamInput;
        pPrmS_ID->Value = vtS_ID;
        pCmdWriteLog->Parameters->Append(pPrmS_ID); TESTHR(pPrmLogTime.CreateInstance(__uuidof(Parameter)));
        pPrmLogTime->Type = adDBTimeStamp;
        pPrmLogTime->Size = 8;
        pPrmLogTime->Direction = adParamInput;
        pPrmLogTime->Value = vtLogTime;
        pCmdWriteLog->Parameters->Append(pPrmLogTime); pCmdWriteLog->Execute(NULL,NULL,adExecuteNoRecords);
这段代码中strC_ID,strC_ID,stLogTime是函数传递进来的参数,类型分别为char*,char*,SYSTEMTIME*。
现在这段代码中有两个问题,我不知道原因是什么。
一个是给pPrmC_ID->Value,pPrmS_ID->Value 赋值时出错,内容是 "应用程序在当前操作中使用了错误类型的值。"。
一个是如果将pPrmLogTime传递进去后,ado的库出错,显示内存访问违规,如果将pPrmLogTime部分注释掉同时修改存储过程相应部分,没有这个错误。请问各位高手,我的程序出错在什么地方,该如何解决?请指教。

解决方案 »

  1.   

    传入参数不要使用VT_BYREF,这个标志是用来接收传出参数值的。另,strC_ID是什么类型的变量?
      

  2.   

    我不使用VT_BYREF后,第一个问题仍然没有解决。strC_ID的类型是 char*
      

  3.   

    如果传递字符串,就不要用VT_UI1了,用VT_BSTR:
    V_VT(&vtC_ID) = VT_BSTR;
    V_BSTR(&vtC_ID) = ::SysAllocString(strC_ID);如果仅仅传递一个字符,那么应该取串中的第一个字符值:
    V_VT(&vtC_ID) = VT_UI1;
    V_UI1(&vtC_ID) = strC_ID[0];自己看看是哪种情况吧。
      

  4.   

    感谢jameshooo的关注。第二个问题已经解决,就是不用VT_BYREF。谢谢我刚使用了V_VT(&vtC_ID) = VT_UI1; V_UI1(&vtC_ID) = strC_ID[0]; 
    但是还是提示"应用程序在当前操作中使用了错误类型的值。"昨晚研究了一晚上,试用了几个方法,也用“Application uses a value of the wrong type for the current operation”作为关键词搜索英文网站,都没有提示准确解决办法。较多的提示就是检查数据表、存储过程和C++变量之间的数据类型和长度是否一致。我检查了我的程序这一点应该是没有问题的。
    在搜索网上的资料时我发现一个共同的特点就是问题都出在使用存储过程,而且存储过程有字符型参数。
    后来我试着在C++代码中将两个字符型parameter的size设置为2,编译链接,用“1”和“2”测试,没有出现"应用程序在当前操作中使用了错误类型的值。",记录插入成功。但是我在sql server management studio查看插入的记录时发现
    c_id = '4',s_id = '5'.呵呵,这是怎么回事?极度纳闷中。
    后来我将数据表和存储过程里的数据长度都改为2,将parameter的size=3(=2时还是出现"应用程序在当前操作中使用了错误类型的值。"),编译链接运行,c_id = '49',s_id = '50',呵呵,恰好是1和2的ascii码。崩溃了。
    我试着不采用存储过程,而是使用带参数的SQL语句,情况相同。考虑到出问题的都是字符参数,于是我将所有的字符参数值直接添加到SQL语句中,插入成功,数据也是正确的。
    这是为什么呢,我的程序错在哪?还是某些设置没有设置正确,比如说字符集?
    自己学艺不精,没法解释,请各位高手指点。
      

  5.   

    可能跟字符集有关,尤其是涉及到字符或者字符串时。我建议你改变一下思路,要么在存储过程里面传递整数类型的参数,要么传递字符串,不要直接传递字符,因为字符集不同,字符所占的字节长度是不一样的,传递整数的好处是没有字符集限制,传递字符串的好处是全部用UNICODE方式传递,数据库自己会翻译成对应的字符集编码。
      

  6.   

    多谢jameshooo的建议。从实现功能的角度来讲传递整数和传递字符串是规避字符集陷阱的好方法。
    但是我还是想解决为什么传递字符就不行呢,问题出在哪,而且会出现将字符变换成ascii码的问题
      

  7.   

    你是给它 c_id char(1),s_id char(1), 传字符串吗?可不可以就不知道了。没见过这么定义的。
      

  8.   

    重金诚聘C++
    http://topic.csdn.net/u/20080227/14/8bce0844-bd15-42f0-9cda-a343d5d6601b.html?seed=2111206245
      

  9.   

    问题已解决,但是还是不知所以然,只有感叹ado太麻烦。 pPrmC_ID-> Value = _variant_t(strC_ID); 
    pPrmS_ID-> Value = _variant_t(strS_ID);