ADO的参数问题,再次提问!!!给300分!!!

freebeekf 2002-02-02 06:01:53
我用了下面的代码来调用一个存储过程
gen_menu(@uno Integer, @level Integer, @lastselect varchar(50))
在运行时总是抛出异常“至少一个参数没有被指定值”,怎么办啊?
下面是测试的存储过程和ADO代码

CREATE PROCEDURE gen_menu(
@uno Integer,@level Integer,@lastselect varchar(50)
) AS
select * from test

GO

_RecordsetPtr rs(__uuidof(Recordset));
rs.CreateInstance(__uuidof(Recordset));//初始化Recordset指针
BOOL ret=TRUE;
long cnt=0;
try{
//--------------------------------------------------------
m_pcommand->PutCommandText(L"call {gen_menu(?,?,?)}");
m_pcommand->PutCommandType(adCmdStoredProc);
m_pcommand->PutCommandTimeout(1000);
_ParameterPtr paramptr;
paramptr = m_pcommand->CreateParameter(_bstr_t("uno"),adInteger,adParamInput,sizeof(long), (long)uno);
m_pcommand->GetParameters()->Append(paramptr);
paramptr = m_pcommand->CreateParameter(_bstr_t("level"),adInteger,adParamInput,sizeof(long), (long)level);
m_pcommand->GetParameters()->Append(paramptr);
paramptr = m_pcommand->CreateParameter(_bstr_t("lastselect"),adVarChar,adParamInput,lastselect.GetLength()+1, _variant_t(lastselect));
m_pcommand->GetParameters()->Append(paramptr);
rs->Open((_Command*)m_pcommand,vtMissing,adOpenForwardOnly,adLockOptimistic,adCmdStoredProc);
rs->Fields->get_Count(&cnt);
if(cnt!=1) ret=FALSE;
else{
v.clear();
while(!rs->Get_EOF()){
string =(LPCTSTR)_bstr_t(rs->GetCollect(L"prop_value"));
v.push_back(s);
}
}
//--------------------------------------------------------
}
catch(_com_error& e){
ErrorsPtr pErrors=m_pconnection->GetErrors();
if(pErrors->GetCount()==0)
{
AfxMessageBox(e.ErrorMessage());
}
else
{
for(int i=0;i<pErrors->GetCount();i++)
{
_bstr_t esc=pErrors->GetItem((long)i)->GetDescription();
AfxMessageBox(desc);
}
}
}
catch(...)
{
AfxMessageBox("some exception occured");
}
rs->Close();
return ret;


...全文
125 12 打赏 收藏 举报
写回复
12 条回复
切换为时间正序
当前发帖距今超过3年,不再开放新的回复
发表回复
liaocao 2002-02-06
PutCommandText(L"call {gen_menu(?,?,?)}");
改成PutCommandText(L"gen_menu");
就能搞定
  • 打赏
  • 举报
回复
masterz 2002-02-02
//execute stored procedure , get returned value, output value, and returned recordset.
#include "stdafx.h"
#import "C:\PROGRA~1\COMMON~1\System\ado\msado15.dll" rename( "EOF", "adoEOF" )
struct InitOle
{
InitOle() { ::CoInitialize(NULL); }
~InitOle() { ::CoUninitialize(); }
} _init_InitOle_;
void PrintProviderError(ADODB::_ConnectionPtr pConnection);

int main(int argc, char* argv[])
{
printf("Create a adParamReturnValue for Command object to get return value of stored procedure\n");
printf("Reference :MSDN---Append and CreateParameter Methods Example (VC++)\n");
ADODB::_ConnectionPtr Conn1;
ADODB::_CommandPtr Cmd1;
ADODB::_RecordsetPtr Rs1;
ADODB::_ParameterPtr retParam= NULL;
ADODB::_ParameterPtr inParam=NULL;
ADODB::_ParameterPtr outParam=NULL;
_variant_t vtEmpty (DISP_E_PARAMNOTFOUND, VT_ERROR);
_variant_t vtEmpty2 (DISP_E_PARAMNOTFOUND, VT_ERROR);
_bstr_t bstrConnect( L"driver={sql server};server=Cell;Database=zhg;UID=sa;PWD=;" );
// the following stored procedure return 12345 int value
_bstr_t bstrCreate ( L"create proc sp_AdoTest( @OutParam int OUTPUT,@InParam int ) "
L"as "
L"select @OutParam = @InParam + 10 "
L"select * from Table1"
L"return 12345" );
_bstr_t bstrSP(L"sp_Adotest" );
try
{
_bstr_t bstrEmpty;
Conn1.CreateInstance( __uuidof( ADODB::Connection ) );
Cmd1.CreateInstance( __uuidof( ADODB::Command ) );
Rs1.CreateInstance(__uuidof(ADODB::Recordset));
// Establish connection.
Conn1->ConnectionString = bstrConnect;
Conn1->Open( bstrConnect, bstrEmpty, bstrEmpty, -1 );
// Open recordset.
Cmd1->ActiveConnection = Conn1;
Cmd1->CommandText = bstrSP;
Cmd1->CommandType = ADODB::adCmdStoredProc;
retParam=Cmd1->CreateParameter(_bstr_t("Return"),ADODB::adInteger,ADODB::adParamReturnValue,sizeof(int));
Cmd1->Parameters->Append(retParam);
outParam = Cmd1->CreateParameter(_bstr_t("OutParam"),ADODB::adInteger,ADODB::adParamOutput,sizeof(int));
Cmd1->Parameters->Append(outParam);
inParam = Cmd1->CreateParameter(_bstr_t("InParam"),ADODB::adInteger,ADODB::adParamInput,sizeof(int),_variant_t( (long) 10 ));
inParam->Value=_variant_t( (long) 10 );
Cmd1->Parameters->Append(inParam);
Cmd1->Parameters->Refresh();
Cmd1->Parameters->Item[ _variant_t( _bstr_t("@InParam") ) ]->Value =_variant_t( (long) 11 );
Rs1->put_CursorLocation(ADODB::adUseClient);
Rs1->Open((_variant_t((IDispatch *) Cmd1)),vtEmpty,ADODB::adOpenStatic,
ADODB::adLockReadOnly, -1);
// Get return value of the stored procedure.adCmdUnknown
TCHAR tcbuf[1024];
long retvalue=Cmd1->Parameters->Item[(short)0]->Value;
long p2=Cmd1->Parameters->Item[(short)1]->Value;
long p3=Cmd1->Parameters->Item[(short)2]->Value;
int recordcount=0;
if(Rs1->State==ADODB::adStateClosed)
MessageBox(NULL,"no recordset is returned from the stored procedure","Information",MB_OK);
else
recordcount = Rs1->GetRecordCount();
wsprintf(tcbuf,"retvalue of the stored procedure:%d,input value:%d,output value:%d,record count :%d",retvalue,p2,p3,recordcount);
MessageBox(NULL,tcbuf,"Output",MB_OK);
}
catch(_com_error &e)
{
_bstr_t bstrSource(e.Source());
_bstr_t bstrDescription(e.Description());
printf("\nCOM error occurred, Source : %s \n Description : %s \n",(LPCSTR)bstrSource,(LPCSTR)bstrDescription);
PrintProviderError(Conn1);
}
return 0;
}



VOID PrintProviderError(ADODB::_ConnectionPtr pConnection)
{
// Print Provider Errors from Connection object.
// pErr is a record object in the Connection's Error collection.
ADODB::ErrorPtr pErr = NULL;
long nCount = 0;
long i = 0;

if( (pConnection->Errors->Count) > 0)
{
nCount = pConnection->Errors->Count;
// Collection ranges from 0 to nCount -1.
for(i = 0; i < nCount; i++)
{
pErr = pConnection->Errors->GetItem(i);
printf("\n\t Error number: %x\t%s", pErr->Number, (LPCSTR)pErr->Description);
}
}
}
  • 打赏
  • 举报
回复
swordflying 2002-02-02
以前我写了在装有vc的机器运行正常,但在没装VC的机器上就有异常
  • 打赏
  • 举报
回复
igand 2002-02-02
恩恩恩
  • 打赏
  • 举报
回复
kakaxixi_008 2002-02-02
我觉得楼上的说的有一定的道理。比如在Delphi 5中对ADO的调用就有很多BUG,须安装升级补丁才行。
  • 打赏
  • 举报
回复
liaocao 2002-02-02
会不会是ADO的BUG?记得CB的ADO在装有SQL Server的机器上会出错。

你还是保持用SQLServer的老习惯吧?
  • 打赏
  • 举报
回复
jucee 2002-02-02
学习
  • 打赏
  • 举报
回复
Lchaos 2002-02-02
我也觉得可以直接使用Execute语句的,这样也方便调用.
另外你最好先试试该存储过程语句在中是否能够执行成功!
  • 打赏
  • 举报
回复
freebeekf 2002-02-02
代码改成了这个样子,还是一样的出错。。。。。。。。。
请大家再帮忙啊!!!我还会加分的!!!
_RecordsetPtr rs(__uuidof(Recordset));
rs.CreateInstance(__uuidof(Recordset));//初始化Recordset指针
BOOL ret=TRUE;
long cnt=0;
try{
//--------------------------------------------------------
m_pcommand->PutCommandText(L"call {gen_menu(?,?,?)}");
m_pcommand->PutCommandType(adCmdStoredProc);
m_pcommand->PutCommandTimeout(1000);
_ParameterPtr paramptr;
paramptr = m_pcommand->CreateParameter(_bstr_t("uno"),adInteger,adParamInput,sizeof(long), (long)uno);
paramptr->Value=(long)uno;
m_pcommand->GetParameters()->Append(paramptr);
paramptr = m_pcommand->CreateParameter(_bstr_t("level"),adInteger,adParamInput,sizeof(long), (long)level);
paramptr->Value=(long)level;
m_pcommand->GetParameters()->Append(paramptr);
paramptr = m_pcommand->CreateParameter(_bstr_t("lastselect"),adVarChar,adParamInput,lastselect.GetLength()+1, _variant_t(lastselect));
paramptr->Value=_bstr_t(lastselect);
m_pcommand->GetParameters()->Append(paramptr);
rs->Open((_Command*)m_pcommand,vtMissing,adOpenForwardOnly,adLockOptimistic,adCmdStoredProc);
rs->Fields->get_Count(&cnt);
if(cnt!=1) ret=FALSE;
else{
v.clear();
while(!rs->Get_EOF()){
string s=(LPCTSTR)_bstr_t(rs->GetCollect(L"prop_value"));
v.push_back(s);
}
}
//--------------------------------------------------------
}
catch(_com_error& e){
ErrorsPtr pErrors=m_pconnection->GetErrors();
if(pErrors->GetCount()==0)
{
AfxMessageBox(e.ErrorMessage());
}
else
{
for(int i=0;i<pErrors->GetCount();i++)
{
_bstr_t desc=pErrors->GetItem((long)i)->GetDescription();
AfxMessageBox(desc);
}
}
}
catch(...)
{
AfxMessageBox("some exception occured");
}
rs->Close();
return ret;
  • 打赏
  • 举报
回复
masterz 2002-02-02
下面是MSDN的代码,她对参数赋值2次,可能第2次才生效
// Create Parameter Object.
Param1 = Cmd1->CreateParameter( _bstr_t(L""),
ADODB::adInteger,
ADODB::adParamInput,
-1,
_variant_t( (long) 5) );
Param1->Value = _variant_t( (long) 5 );//set value again
  • 打赏
  • 举报
回复
masterz 2002-02-02
...
paramptr = m_pcommand->CreateParameter(_bstr_t("uno"),adInteger,adParamInput,sizeof(long), (long)uno);
paramptr->Value = _variant_t( (long)uno);
m_pcommand->GetParameters()->Append(paramptr);
paramptr = m_pcommand->CreateParameter(_bstr_t("level"),adInteger,adParamInput,sizeof(long), (long)level);
paramptr->Value = _variant_t( (long)level);
m_pcommand->GetParameters()->Append(paramptr);
paramptr = m_pcommand->CreateParameter(_bstr_t("lastselect"),adVarChar,adParamInput,lastselect.GetLength()+1, _variant_t(lastselect));
paramptr->Value = _variant_t(lastselect));
...
  • 打赏
  • 举报
回复
itmask 2002-02-02
你可以用_RecordsetPtr的Open方法直接调用存储过程,这样方便的多。
例:m_pRecordset->Open("execute gen_menu uno levelnteger lastselect",
IDispatch*)m_pConnection,
adOpenDynamic,
adLockOptimistic,
adCmdText)

注:具体参数具体赋值
试试吧
  
  • 打赏
  • 举报
回复
相关推荐
发帖
VC/MFC
加入

1.6w+

社区成员

VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Web++
  • encoderlee
申请成为版主
帖子事件
创建了帖子
2002-02-02 06:01
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……