以下就是 http://community.csdn.net/Expert/FAQ/FAQ_Index.asp?id=197210 帖子的内容,希望对楼主有所帮助。VC++如何调用带参数的存储过程 并且参数中有输出参数 和返回值 --------------------------------------------------------------- 在vc中通过ODBC(不要ADO)调用 CREATE PROCEDURE Test @Para1 int , @Para2 int , @Para3 int , @Ret int OUTPUT AS insert into test1 values (@Para1,@Para2,@Para3) set @Ret = @Para1; GO /////////////////////////////////////////////////////////////////////////////// jnxulei(石头) ( ) 信誉:111 //------------------------------------------------------------------------------ CDatabase * pDatabase = new CDatabase;
_variant_t varReturnCode;pReturnCode = pCommand->CreateParameter( "ReturnValue",
ADODB::adInteger,
ADODB::adParamReturnValue,
sizeof(int),
varReturnCode );
pCommand->Parameters->Append( pReturnCode );
pCommand->Execute( NULL,NULL,ADODB::adCmdStoredProc);执行存储过程,返回值就存在pReturnCode
上面
http://community.csdn.net/Expert/FAQ/FAQ_Index.asp?id=197210
的网址不太好使,我希望处理存储过程中的return
---------------------------------------------------------------
在vc中通过ODBC(不要ADO)调用
CREATE PROCEDURE Test
@Para1 int ,
@Para2 int ,
@Para3 int ,
@Ret int OUTPUT
AS
insert into test1 values (@Para1,@Para2,@Para3)
set @Ret = @Para1;
GO
///////////////////////////////////////////////////////////////////////////////
jnxulei(石头) ( ) 信誉:111
//------------------------------------------------------------------------------
CDatabase * pDatabase = new CDatabase;
pDatabase->OpenEx("DSN=ODBCName;UID=***;PWD=***", 0 );
CRecordset rs( pDatabase );
SQL.Format("{Test %d,%d,%d,%d}",Time0, Time1, Time2, Time3);
rs.Open( CRecordset::dynamic, SQL, CRecordset::none );
rs.GetFieldValue( (long)0, strReturn );
rs.Close();
pDatabase->Close();
delete pDatabase;
///////////////////////////////////////////////////////////////////////////////
lsp5i5j(星辰->女人在哪) ( ) 信誉:87
//------------------------------------------------------------------------------
ODBC有点麻烦,输入输出参数都有
int SimpleGetAccordOtherprocedure(CDatabase *dbCust,char *spstring,char *resultp,int *resultplen,int *ireturn,int *nIndex,char *sUserTel,char *sOtherId,char *sOtherTel,char *sOtherSex,char *sOtherOld)
{
char spstm[512];
int ret;
HSTMT hStmt;
int totallen=0;
SDWORD cbIn1=SQL_NTS, cbIn2=SQL_NTS, cbOut=1024,cbRet=0;
ret=SQLAllocStmt(dbCust->m_hdbc, &hStmt);
if(ret!=SQL_SUCCESS && ret!=SQL_SUCCESS_WITH_INFO)
return(-3503);
if(sizeof(spstm)<=strlen(spstring))
return(-3504);
strcpy(spstm,spstring);
ret=SQLPrepare(hStmt, (UCHAR *)spstm, SQL_NTS);
if(ret!=SQL_SUCCESS && ret!=SQL_SUCCESS_WITH_INFO)
return(-3504);
ret=SQLBindParameter(hStmt,1,SQL_PARAM_OUTPUT,SQL_C_SSHORT,SQL_INTEGER, 0, 0, ireturn, 0,&cbRet);
ret=SQLBindParameter(hStmt,2,SQL_PARAM_INPUT,SQL_C_SSHORT,SQL_INTEGER,0, 0, nIndex, 0, &cbIn1);
ret=SQLBindParameter(hStmt,3,SQL_PARAM_INPUT,SQL_C_CHAR,SQL_CHAR, DBACCESS_MAXPARAMLEN, 0, sUserTel, DBACCESS_MAXPARAMLEN,&cbIn1);
ret=SQLBindParameter(hStmt,4,SQL_PARAM_OUTPUT,SQL_C_CHAR,SQL_CHAR, DBACCESS_MAXPARAMLEN, 0, sOtherId, DBACCESS_MAXPARAMLEN,&cbIn2);
ret=SQLBindParameter(hStmt,5,SQL_PARAM_OUTPUT,SQL_C_CHAR,SQL_CHAR, DBACCESS_MAXPARAMLEN, 0, sOtherTel, DBACCESS_MAXPARAMLEN,&cbIn1);
ret=SQLBindParameter(hStmt,6,SQL_PARAM_INPUT,SQL_C_CHAR,SQL_CHAR, DBACCESS_MAXPARAMLEN, 0, sOtherSex, DBACCESS_MAXPARAMLEN,&cbIn1);
ret=SQLBindParameter(hStmt,7,SQL_PARAM_INPUT,SQL_C_CHAR,SQL_CHAR, DBACCESS_MAXPARAMLEN, 0, sOtherOld, DBACCESS_MAXPARAMLEN,&cbIn1);
ret=SQLExecute(hStmt);
if(ret!=SQL_SUCCESS && ret!=SQL_SUCCESS_WITH_INFO)
return(-3505); // printf("Error in execute!\n");
ret=TBSDBProcWU(hStmt,resultp,resultplen);
return ret;
}
我只会把数据存在 OUTPUT 的参数里面,拿回来。
具体的过程在此我不详细描述,我想看看本文附带的代码就应该很明白了。
在这里我想就我使用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();