用ADO调用存储过程,想得到返回值,我这么写有什么问题?

时间:2021-05-13 09:45:09
// 有三个输入参数(用户名,密码,权限),一个输出参数
CString strText;
short userID = 2;
char  strPass[8] = "aaa33";
long Limit = 1;
long ret = 33;
long ret2 =35;      

CAdoCommand adoComd;          // CAdoCommand是封装_CommandPtr的一个类
_ParameterPtr para[4];

para[0].CreateInstance("ADODB.Parameter");
para[1].CreateInstance("ADODB.Parameter");
para[2].CreateInstance("ADODB.Parameter");
para[3].CreateInstance("ADODB.Parameter");
 
strText.Format("ret = %d", ret);
MessageBox(strText);

adoComd.SetConnection(&m_adoConnection);  // m_adoConnection数据库已经连接上
adoComd.SetCommandText("LoginProc");
adoComd.SetCommandType(adCmdStoredProc);
    
// 第一个输入参数 (用户名)
para[0] = adoComd.CreateParameter("", adInteger,adParamInput, 2,_variant_t(WorkID)); 
adoComd.Append(para[0]);

// 第二个输入参数 (密码)
para[1] = adoComd.CreateParameter("", adBSTR, adParamInput, 8, _variant_t(strPass)); 
adoComd.Append(para[1]);    

// 第三个输入参数 (权限)
para[2] = adoComd.CreateParameter("", adInteger,adParamInput, 4, variant_t(Limit)); 
adoComd.Append(para[2]);

// 输出参数
para[3] = adoComd.CreateParameter("ret", adInteger, adParamOutput, 4, variant_t(ret2)); 
adoComd.Append(para[3]);    
    
adoComd.Execute();

ret = vartol(para[3]->Value);  // 想得到输出参数的值

strText.Format("ret = %d", ret);
MessageBox(strText);


这行这段代码的时候,有异常,提示函数或过程LoginProc指定的参数太多!如果我把这部分屏蔽掉:
para[3] = adoComd.CreateParameter("ret", adInteger, adParamOutput, 4, _variant_t(ret2)); 
adoComd.Append(para[3]);    

就没有提示错误了,但是我还要获得返回值,怎么获得这个值?是我调用存储过程的方法不对,还是存储过程写的不对,存储过程查询分析器里执行是对的啊? 

以下是存储过程:(返回@iReturnCode)

CREATE   PROCEDURE [LoginProc] 

@iYGCode smallint,  --员工编号
@cPassword varchar(8),--密码
@iLtd int  --权限

AS

declare @iReturnCode int
declare @iYGNum int

set @iReturnCode=0   --成功

select  @iYGNum =(count(*)) from Worker where Valid=1 and YGCode=@iYGCode
if(@iYGNum=0)
set @iReturnCode=4  --员工号错误
else
begin
    select @iYGNum =(count(*)) from Worker where Valid=1 and YGCode=@iYGCode and [Password]=@cPassword
if(@iYGNum=0)
set @iReturnCode=5  --密码错误
     else
begin
select @iYGNum =( count(*)) from Worker where Valid=1 and YGCode=@iYGCode and YGLtd=@iLtd and [Password]=@cPassword

if(@iYGNum=0)
set @iReturnCode=6  --权限错误
         end
end
return @iReturnCode
GO  

7 个解决方案

#1


para[3] = adoComd.CreateParameter("ret", adInteger, adParamOutput, 4, _variant_t(ret2)); 
adoComd.Append(para[3]);    
这是定义输出参数(Output) 你现在没有这个参数,当然指定的参数太多。
返回值应用如下代码:
pParam5 = pCmd->CreateParameter(_bstr_t("Return"), adInteger, adParamReturnValue, 2);

#2


adParamOutput换成adParamReturnValue就行。

#3


改为adParamReturnValue还是不行啊,还是提示参数太多!
adoComd.Append(para[3]);这句还需要加吗?如果把它去掉的话得不到返回值啊?    

#4


下面代码是我以前做的例子,可以执行,你参考一下。

void CProcParameterDlg::OnBtnExec() 
{
// TODO: Add your control notification handler code here
UpdateData();

_ConnectionPtr pConn;
//_RecordsetPtr pReco;
_CommandPtr pCmd;
_ParameterPtr pParam1, pParam2, pParam3, pParam4, pParam5;
try
{
pConn.CreateInstance("ADODB.Connection");
pConn->Open("Provider=SQLOLEDB;SERVER=Name;DATABASE=Pubs;UID=sa;PWD=",
"", "", -1);
//pReco.CreateInstance("ADODB.Recordset");
pCmd.CreateInstance(__uuidof(Command));

pCmd->ActiveConnection = pConn;
pCmd->CommandType = adCmdStoredProc;
pCmd->CommandText = "TestParam";

pParam5 = pCmd->CreateParameter(_bstr_t("Return"), adInteger, adParamReturnValue, 2);
pCmd->Parameters->Append(pParam5);

pParam3 = pCmd->CreateParameter(_bstr_t("@nParam3"), adInteger, adParamOutput, 4);
pCmd->Parameters->Append((IDispatch*)(pParam3));
pParam4 = pCmd->CreateParameter(_bstr_t("Output2"), adVarChar, adParamOutput, 20);
pCmd->Parameters->Append(pParam4);

pParam1 = pCmd->CreateParameter(_bstr_t("Input1"), adInteger, adParamInput, 4);
pCmd->Parameters->Append(pParam1);
pParam2 = pCmd->CreateParameter(_bstr_t("Input2"), adVarChar, adParamInput, 20);
pCmd->Parameters->Append(pParam2);

pParam2->Value = _variant_t(m_strInput2);
pParam1->Value = _variant_t((short)m_nInput1);

pCmd->Execute(NULL, NULL, adCmdStoredProc);

m_nOutput3 = (pParam3->Value).intVal;
m_nRetValue = (pParam5->Value).intVal;
m_strOutput4 = (char*)_bstr_t(pParam4->Value);
UpdateData(FALSE);

}
catch(_com_error e) // 捕捉异常
{
_bstr_t bstrSource(e.Source());
_bstr_t bs =  _bstr_t(" Error: ") + _bstr_t(e.Error()) + _bstr_t(" Msg: ") 
+ _bstr_t(e.ErrorMessage()) + _bstr_t(" Description: ") 
+ _bstr_t(e.Description());
MessageBox(bs, bstrSource);
}
}

#5


CREATE  PROC TestParam @nParam3 int OUTPUT,
                       @strParam4 varchar(50) OUTPUT,
                       @nParam1 int,
                       @strParam2 varchar(50)
                     
AS

SET @nParam3 = @nParam1
SET @strParam4 = @strParam2

IF @nParam1 > 100
   RETURN 1
ELSE
   RETURN -1
GO

#6


{
        long WorkID = 2;
        long ret = 33;
        CString strText;
 
        CAdoCommand adoComd;
        _ParameterPtr InputPara, RetPara;
       
        InputPara.CreateInstance("ADODB.Parameter");
        RetPara.CreateInstance("ADODB.Parameter");

        strText.Format("ret = %d", ret);
        MessageBox(strText);

        adoComd.SetConnection(&m_adoConnection);
        adoComd.SetCommandText("TestProc");
        adoComd.SetCommandType(adCmdStoredProc);

        InputPara = adoComd.CreateParameter("", adInteger,adParamInput, 4,  
                                            _variant_t(WorkID)); 
        adoComd.Append(InputPara);

        RetPara = adoComd.CreateParamete("Return",adInteger,adParamReturnValue,
                                          4, _variant_t(ret)); 
        adoComd.Append(RetPara);

        adoComd.Execute();

        ret = vartol(RetPara->Value);

        strText.Format("ret = %d", ret);
        MessageBox(strText);

}

存储过程如下:
CREATE proc TestProc @nParam int

as

if @nParam < 10
return 1
else
return 2
GO

但是还是提示参数太多?????

#7


你试试我给你的代码能否执行,如果没问题,那CAdoCommand封装_CommandPtr的类说不定有问题。

#1


para[3] = adoComd.CreateParameter("ret", adInteger, adParamOutput, 4, _variant_t(ret2)); 
adoComd.Append(para[3]);    
这是定义输出参数(Output) 你现在没有这个参数,当然指定的参数太多。
返回值应用如下代码:
pParam5 = pCmd->CreateParameter(_bstr_t("Return"), adInteger, adParamReturnValue, 2);

#2


adParamOutput换成adParamReturnValue就行。

#3


改为adParamReturnValue还是不行啊,还是提示参数太多!
adoComd.Append(para[3]);这句还需要加吗?如果把它去掉的话得不到返回值啊?    

#4


下面代码是我以前做的例子,可以执行,你参考一下。

void CProcParameterDlg::OnBtnExec() 
{
// TODO: Add your control notification handler code here
UpdateData();

_ConnectionPtr pConn;
//_RecordsetPtr pReco;
_CommandPtr pCmd;
_ParameterPtr pParam1, pParam2, pParam3, pParam4, pParam5;
try
{
pConn.CreateInstance("ADODB.Connection");
pConn->Open("Provider=SQLOLEDB;SERVER=Name;DATABASE=Pubs;UID=sa;PWD=",
"", "", -1);
//pReco.CreateInstance("ADODB.Recordset");
pCmd.CreateInstance(__uuidof(Command));

pCmd->ActiveConnection = pConn;
pCmd->CommandType = adCmdStoredProc;
pCmd->CommandText = "TestParam";

pParam5 = pCmd->CreateParameter(_bstr_t("Return"), adInteger, adParamReturnValue, 2);
pCmd->Parameters->Append(pParam5);

pParam3 = pCmd->CreateParameter(_bstr_t("@nParam3"), adInteger, adParamOutput, 4);
pCmd->Parameters->Append((IDispatch*)(pParam3));
pParam4 = pCmd->CreateParameter(_bstr_t("Output2"), adVarChar, adParamOutput, 20);
pCmd->Parameters->Append(pParam4);

pParam1 = pCmd->CreateParameter(_bstr_t("Input1"), adInteger, adParamInput, 4);
pCmd->Parameters->Append(pParam1);
pParam2 = pCmd->CreateParameter(_bstr_t("Input2"), adVarChar, adParamInput, 20);
pCmd->Parameters->Append(pParam2);

pParam2->Value = _variant_t(m_strInput2);
pParam1->Value = _variant_t((short)m_nInput1);

pCmd->Execute(NULL, NULL, adCmdStoredProc);

m_nOutput3 = (pParam3->Value).intVal;
m_nRetValue = (pParam5->Value).intVal;
m_strOutput4 = (char*)_bstr_t(pParam4->Value);
UpdateData(FALSE);

}
catch(_com_error e) // 捕捉异常
{
_bstr_t bstrSource(e.Source());
_bstr_t bs =  _bstr_t(" Error: ") + _bstr_t(e.Error()) + _bstr_t(" Msg: ") 
+ _bstr_t(e.ErrorMessage()) + _bstr_t(" Description: ") 
+ _bstr_t(e.Description());
MessageBox(bs, bstrSource);
}
}

#5


CREATE  PROC TestParam @nParam3 int OUTPUT,
                       @strParam4 varchar(50) OUTPUT,
                       @nParam1 int,
                       @strParam2 varchar(50)
                     
AS

SET @nParam3 = @nParam1
SET @strParam4 = @strParam2

IF @nParam1 > 100
   RETURN 1
ELSE
   RETURN -1
GO

#6


{
        long WorkID = 2;
        long ret = 33;
        CString strText;
 
        CAdoCommand adoComd;
        _ParameterPtr InputPara, RetPara;
       
        InputPara.CreateInstance("ADODB.Parameter");
        RetPara.CreateInstance("ADODB.Parameter");

        strText.Format("ret = %d", ret);
        MessageBox(strText);

        adoComd.SetConnection(&m_adoConnection);
        adoComd.SetCommandText("TestProc");
        adoComd.SetCommandType(adCmdStoredProc);

        InputPara = adoComd.CreateParameter("", adInteger,adParamInput, 4,  
                                            _variant_t(WorkID)); 
        adoComd.Append(InputPara);

        RetPara = adoComd.CreateParamete("Return",adInteger,adParamReturnValue,
                                          4, _variant_t(ret)); 
        adoComd.Append(RetPara);

        adoComd.Execute();

        ret = vartol(RetPara->Value);

        strText.Format("ret = %d", ret);
        MessageBox(strText);

}

存储过程如下:
CREATE proc TestProc @nParam int

as

if @nParam < 10
return 1
else
return 2
GO

但是还是提示参数太多?????

#7


你试试我给你的代码能否执行,如果没问题,那CAdoCommand封装_CommandPtr的类说不定有问题。