C++用ADO连SQL数据库 如何直接得到存储过程的@ReturnValue  急

解决方案 »

  1.   

    m_pParam5 = m_pCommand->CreateParameter("Kingdom",adChar,adParamInput,32,"zhonggg");另外还想问下 如果我这里的输入参数 不是adChar的 在数据库里是要存的image型 应该怎么办 是ad什么?
    _ParameterPtr m_pParam1;//附加数字的命名习惯不好别学我啊
    m_pParam1.CreateInstance("ADODB.Parameter"); _ParameterPtr m_pParam2;
    m_pParam2.CreateInstance("ADODB.Parameter");  _ParameterPtr m_pParamRet;
    m_pParamRet.CreateInstance("ADODB.Parameter");
    m_pParam1 = m_pCommand->CreateParameter("Account",adVarChar,adParamInput,32,(_variant_t)szAccount.Trim());//给参数设置各属性
    m_pCommand->Parameters->Append(m_pParam1);//加入到Command对象的参数集属性中 m_pParam2 = m_pCommand->CreateParameter("Name",adVarChar,adParamInput,32,(_variant_t)Name.Trim());
    m_pCommand->Parameters->Append(m_pParam2); m_pParamRet=m_pCommand->CreateParameter("ErrMsg",adVarChar,adParamOutput,128);
    m_pCommand->Parameters->Append(m_pParamRet);
    m_pCommand->Execute(0,NULL,adCmdStoredProc); CString xx =  (TCHAR*)(_bstr_t)m_pParamRet->Value;还有就是我这么写 我这里为什么得不到ErrMsg的值呢?
      

  2.   

    能得到ErrMsg的值  但是存储过程里写的直接Return的那个值我怎么得到呢
      

  3.   

    C++怎么搞不知道,如果是SQL,看你另外一个帖.http://topic.csdn.net/u/20090328/10/9bb8f603-6e88-487e-a0d8-602e024523f6.html?931924085
      

  4.   

    网络上转贴的希望对你有帮助
    使用ADO调用存储过程
        在ADO中调用存储过程一直是一个困扰大家的问题。其实,关于ADO调用存储过程的   方法在很多书中都有讲到,标准的做法无非是按照以下步骤进行:    1、生成并初始化一个_CommandPtr对象;    2、生成调用存储过程需要的参数,这些参数都是_ParameterPtr对象;    3、按照顺序将使用_CommandPtr的Append方法为存储过程提供参数(包括输入参数       和输出参数);    4、为_CommandPtr对象指定需要使用的ADO连接;    5、使用_CommandPtr的Execute方法调用存储过程;    6、从结果中获取返回参数的值(如果有的话)。
       具体的过程在此我不详细描述,我想看看本文附带的代码就应该很明白了。
       在这里我想就我使用ADO调用存储过程时的一些体会说明一下。
      1、关于CreateParameter函数
       该函数的原型为:CreateParameter (Name, Type, Direction, Size, Value)
       其中Name是参数的名称,可以指定也可以不指定;   Type是一个DataTypeEnum值,指定参数的类别,取值有adInteger(整型)、adChar(字符/字符串型)等;   Direction是一个ParameterDirectionEnum值,其取值为adParamInput、adParamInputOutput、   adParamOutput、adParamReturnValue、adParamUnknown;   Size是一个Long类型的值,指示该参数值以字节计算的最大长度,例如对int型,该值可以取为sizeof(int),   对Long型,该值可以取为sizeof(long),对字符串型,可以使用该字符串的长度;   Value是一个variant类型的值,是该参数的取值。
       在这里需要注意的是,Type参数、Direction参数以及Size参数一定要和存储过程定义时的参数相吻合,
       例如,如果有下面一个存储过程   CREATE  PROCEDURE SMS_Proc_Handle_All   (@UserID Integer,    @SourAddr Varchar(15),    @DestAddr varchar(5000),    @AvValue Single output,    @ReturnInfo varchar(100) output   )   则Type参数的取值依次为adInteger、adChar、adChar、adSingle,adChar;   Direction参数的取值依次为adParameterIn、adParameterIn、adParameterIn、adParameterOut、adParameterOut;   对于输入参数,Size的值可以根据实际数值来定,对于输出参数,最好是根据定义确定(上例中ReturnInfo参数的   Size值可以取为100)。
       2,关于获取Output的参数
         获取ourput参数是大家最关注的问题,同时也是最“难”的问题,因为按照书本上的写法,经常获得不了   Output参数,其实这个问题很容易解决:在调用_CommandPtr的Execute方法时,写成   cmmd->Execute(NULL, NULL, adCmdStoredProc);   而不要写成   RecordsetPtr rec = cmmd->Execute(NULL, NULL, adCmdStoredProc);   也就是说,不取返回值(我不知道这是为什么,但是相信我,事情就是这样)。   这句执行完后,使用   cmmd->Parameters->GetItem("XXXXXX")->GetValue();                          ^^^^^^^                        输出参数的名称   就可以获得输出参数的值了。
       以下是一个通过ADO调用存储过程的部分代码:
      _CommandPtr cmmd;  HRESULT hr = cmmd.CreateInstance(__uuidof(Command));  if(FAILED(hr))  {   AfxMessageBox("NewNetDatabase()中创建_CommandPtr对象失败");   return 0;  }  _ParameterPtr param;  param = cmmd->CreateParameter(""/*NetType*/,adTinyInt, adParamInput,    sizeof(BYTE),(BYTE)(m_nNetType+1));  cmmd->Parameters->Append(param);  param = cmmd->CreateParameter(""/*Name*/,adVarChar, adParamInput,   m_strName.GetLength()+1, _variant_t(m_strName));  cmmd->Parameters->Append(param);  param = cmmd->CreateParameter(""/*Desp*/,adVarChar, adParamInput,   m_strDesp.GetLength()+1, _variant_t(m_strDesp));  cmmd->Parameters->Append(param);  param = cmmd->CreateParameter("NewNetID"/*NetID*/,adInteger, adParamOutput,   sizeof(long), (long)m_nNewNetID);//返回参数,返回新建的网络的ID  cmmd->Parameters->Append(param);   cmmd->CommandText=_bstr_t("GSDT_NewNet");//存储过程的名称  cmmd->ActiveConnection = m_pConPtr;//需要使用的ADO连接  cmmd->CommandType=adCmdStoredProc;  //注意下面的一行代码,如果你写成这样,就获得不了返回参数的值  //_RecordsetPtr rec = cmmd->Execute(NULL, NULL, adCmdStoredProc);  //我不知道这是为什么,但事实就是这样:)  cmmd->Execute(NULL, NULL, adCmdStoredProc);  m_nNewNetID=(long)cmmd->Parameters->GetItem("NewNetID")->GetValue();//通过参数返回值  cmmd.Detach();
      

  5.   

    vcado:VC中使用ADO调用存储过程实现方

    疯狂代码 http://www.crazycoder.cn/ ĵ:http:/www.crazycoder.cn/VC/Article13190.html
    开发环境是VS2005 ,数据库是SQL Sever 2000
    1. 在进入正题的前先讲点别如何在VC中连接Sybase数据库
    连接窜为
    _bstr_t strCnn(\"Driver={Sybase 11};Srvr=RRRRR;Uid=RRR_Mao_bb1;Pwd=user2\");
    这里RRRRR是数据库名称已经在Sybase->sdedit中设定好了
    RRR_Mao_bb1 和 user2分别是用户名和密码
    不过使用这种基于ODBC连接使用段时间以后就出现问题了出现了“Catastrophic failure”微软解释是
    http://support.microsoft.com/kb/243349/en-us
    2. 为了使我们存储过程例子有更多通用性我建了有输入参数有输出参数有个返回记录集有个返回值存储过程如

    CREATE PROCEDURE sp_1 (
    @pin1 ,
    @pin2 CHAR(10),
    @pout1 OUTPUT,
    @pout2 CHAR(10) OUTPUT
    )
    AS
    BEGIN
    declare @retval
    select @pout1 = @pin1 + 100
    select @pout2 = left( ltrim(rtrim(@pin2)) + \'123\' , 10)
    select Num,Name,Date
    from TABLE1
    select @retval = 1236
    @retval
    END
    对于这个SP来说他这些个参数是
    @RETURN_VALUE( ,返回值)
    @pin1 ( ,输入 )
    @pin2 ( char(10) ,输入 )
    @pout1 ( ,输入/输出)
    @pout1 ( char(10) , 输入/输出)
    @RETURN_VALUE是第0个参数@pin1是第1个依此类推
    以上信息可以在SQL 查询分析器中看到注意这些参数顺序很重要
    3.前期准备
    这就不多说了什么import 库阿建立连接阿什么不多说了
    这些在VC中使用ADO进行数据库开发些资料整理 中有了阐述
    假定连接是pConn
    注意这里要把pConn设定成adUseClient型[Page]
    pConn->CursorLocation =adUseClient;
    下面我要贴具体代码了为了精简所贴代码我把所有捕获异常都没贴出来(try catch)
    4.使用Refresh思路方法来
    先定义些变量
    _CommandPtr pCmd = NULL;
    _RecordPtr pRecord = NULL;
    初试化他们
    pCmd.CreateInstance(__uuidof(Command));
    pRecord.CreateInstance(_uuidof(Record));
    pCmd->ActiveConnection = pConn;
    pCmd->CommandType = adCmdStoredProc;
    pCmd->CommandText=_bstr_t(_T(\"sp_1\")); //SP Name
    然后给那些input参数赋值
    pCmd->Parameters->Refresh;
    pCmd->Parameters->Item[_variant_t(_bstr_t(\"@pin1\") )]->Value=_variant_t(3);
    pCmd->Parameters->Item[_variant_t(_bstr_t(\"@pin2\") )]->Value=_variant_t(\"DD\");
    这个refresh定要有
    调SP
    pRecord = pCmd->Execute(NULL,NULL,adCmdStoredProc);
    retVal = -1;
    _variant_t VretVal ;
    //GetRetVal
    VretVal = pCmd->Parameters->GetItem((0))->Value;
    retVal = VretVal.lVal;
    Info.Format(_T(\"The Return Value is : %d\"),retVal);
    MessageBox(Info);
    //output1
    VretVal = pCmd->Parameters->GetItem((3))->Value;
    retVal = VretVal.lVal;
    Info.Format(_T(\"The output1 Value is : %d\"),retVal);
    MessageBox(Info);
    //@pout2
    VretVal = pCmd->Parameters->GetItem((4))->Value;
    Info= (LPCTSTR)_bstr_t(VretVal);
    CString info1;
    info1.Format(_T(\"The output2 Value is : %s\"),Info);
    MessageBox(info1);
    //取记录集里面内容
    (pRecord->adoBOF && pRecord->adoEOF)
    {
    MessageBox(\"没有符合条件记录存在!\",\"提示\");
    (pRecord != NULL && pRecord->State)
    {
    pRecord->Close;
    pRecord = NULL;
    }
    pCmd.Detach;
    ;
    }
    pRecord->MoveFirst;
    for(;!pRecord->adoEOF;pRecord->MoveNext)
    {
    VRectVal = pRecord->GetCollect(_T(\"Name\"));
    StrVal = (LPCTSTR)_bstr_t(VRectVal);
    m_list.AddString(StrVal);
    }
    (pRecord != NULL && pRecord->State)
    {
    pRecord->Close;
    pRecord = NULL; [Page]
    }
    最后pCmd.Detach;
    在这里有点要注意是
    VretVal = pCmd->Parameters->GetItem((4))->Value;
    这里4就是哪个output参数index就是我在2中说参数顺序
    这里使用了Refresh这是个很重要我将在下面介绍下它我要先贴出另种不使用Refresh办法
    5 .使用非Refresh思路方法来
    先定义变量
    _CommandPtr pCmd = NULL;
    _RecordPtr pRecord = NULL;
    _ParameterPtr retParam = NULL;
    _ParameterPtr inParam1 = NULL;
    _ParameterPtr inParam2 = NULL;
    _ParameterPtr outParam1 = NULL;
    _ParameterPtr outParam2 = NULL;
    初试化
    pCmd.CreateInstance(__uuidof(Command));
    pRecord.CreateInstance(_uuidof(Record));
    retParam.CreateInstance(__uuidof(Parameter));
    //其他ParameterPtr 也初试化
    pCmd->ActiveConnection = pConn;
    pCmd->CommandType = adCmdStoredProc;
    pCmd->CommandText=_bstr_t(_T(\"sp_1\")); //SP Name
    retParam = pCmd ->CreateParameter(_bstr_t(\"Return\"),
    adInteger,
    adParamReturnValue,
    ());
    pCmd->Parameters->Append(retParam);
    inParam1 = pCmd ->CreateParameter(_bstr_t(\"InParam1\"),
    adInteger,
    adParamInput,
    ());
    inParam1->Value = _variant_t(3);
    pCmd->Parameters->Append(inParam1);
    inParam2 = pCmd ->CreateParameter(_bstr_t(\"InParam2\"),
    adChar,
    adParamInput,[Page]
    10);
    inParam2->Value = _variant_t(_T(\"DD1\"));
    pCmd->Parameters->Append(inParam2);
    outParam1 = pCmd ->CreateParameter(_bstr_t(\"OutParam1\"),
    adInteger,
    adParamOutput,
    ());
    pCmd->Parameters->Append(outParam1);
    outParam2 = pCmd ->CreateParameter(_bstr_t(\"OutParam2\"),
    adChar,
    adParamOutput,
    10);
    pCmd->Parameters->Append(outParam2);
    这里不用refresh办法是用Parameter来这里要注意是这个add顺序要和参数index顺序要致
    下面就是了
    pRecord = pCmd->Execute(NULL,NULL,adCmdStoredProc);
    然后取那些值阿output值阿什么
    这里有个区别就是用这种办法
    可以有 3种办法来取这些返回值和output参数
    VretVal = pCmd->Parameters->GetItem(_bstr_t(\"Return\"))->Value;
    VretVal = pCmd->Parameters->GetItem((0))->Value;
    VretVal = retParam->Value;
    都是样