VC调用MSSQL存储过程

时间:2022-01-25 14:05:37
在VC6里调用一个MSSQL里的存储过程,因为有很多数据要重复调用这个存储过程,但是每次都要CLOSE后再重新连接数据库才能调用它INSERT数据..不然就报错.第一个数据没有问题,后面的都出错.感觉是传入参数没有清空的的原因,用了ptr_insert->Release();还是一样.网上查了很多都没结果.只有一个贴子说用ParameterPtr 的DELETE方法,但是没找到该方法.
请高手给看看:

下面是代码和一些说明:
传入参数:const char* pStoreName,//表名
 const char *pInsert, const char *pUpdate, const char *pTableName,const char *psfid //存储过程input
int& type, int& flag //存储过程output

bool CAdoModule::ExecStoredProc_SfDataUp(const char* pStoreName, const char *pInsert, const char *pUpdate, const char *pTableName,const char *psfid, int& type, int& flag)
{
char sz_msg[256] = {0};
char sz_buf[128] = {0};

//---如果这里不重连,第二次调用此代码里的Execute(&vNULL, &vNULL, adCmdStoredProc);
     //----的是候会跳转到catch (::_com_error e)里并产生#3092的错.
     //----如果调用,该代码不会出错.但是太浪费时间了.每调一次重连一次
     //----个人猜测是在m_pADOCmd->Parameters->Append(ptr_insert); 增加参数这里出错,前面没清除,第二轮又
          //----插入了新的数据,导至参数比我想要传进的参数多,但是我做了ptr_insert->Release();感觉没效
     //---但是如果是UPDATE.却不会出错.只是INSERT出错.求解.....
CloseDb();
if(!ReInitAdo()) return false;

try
{
_variant_t RecordsAffected;
_variant_t vNULL;
_variant_t VretVal; //return
vNULL.vt = VT_ERROR;
vNULL.scode = DISP_E_PARAMNOTFOUND; //定义为无参数
m_pADOCmd->ActiveConnection = m_pADOCon; //非常关键的一句,将建立的连接赋值给它
m_pADOCmd->CommandType = adCmdStoredProc;
//m_pADOCmd->Parameters->Refresh();

//----增加输入参数----
_ParameterPtr ptr_insert;
_ParameterPtr ptr_update;
_ParameterPtr ptr_tablename;
_ParameterPtr ptr_sfid;
_ParameterPtr ptr_out_type;
_ParameterPtr ptr_out_flag;

// char sz_test[4096] = {0};
// strcpy(sz_test, pInsert);
//----input参数
ptr_insert = m_pADOCmd->CreateParameter("@str_insert", adVarChar , adParamInput, 4000, _variant_t(pInsert)) ;
m_pADOCmd->Parameters->Append(ptr_insert); 

// strcpy(sz_test, pUpdate);
ptr_update = m_pADOCmd->CreateParameter("@str_update", adVarChar , adParamInput, 4000, _variant_t(pUpdate)) ;
m_pADOCmd->Parameters->Append(ptr_update);  

ptr_tablename = m_pADOCmd->CreateParameter("@str_tablename", adVarChar, adParamInput, 128, _variant_t(pTableName)) ;
m_pADOCmd->Parameters->Append(ptr_tablename); 

ptr_sfid = m_pADOCmd->CreateParameter("@str_sfid", adVarChar, adParamInput, 32, _variant_t(psfid)) ;
m_pADOCmd->Parameters->Append(ptr_sfid);

char sz_buf[8] = {0};
_snprintf(sz_buf, sizeof(sz_buf) - 1, "%d", type);
ptr_out_type = m_pADOCmd->CreateParameter("@n_type", adInteger, adParamOutput, 8, _variant_t(sz_buf)) ;
m_pADOCmd->Parameters->Append(ptr_out_type);

_snprintf(sz_buf, sizeof(sz_buf) - 1, "%d", flag);
ptr_out_flag = m_pADOCmd->CreateParameter("@n_flag", adInteger, adParamOutput, 8, _variant_t(sz_buf)) ;
m_pADOCmd->Parameters->Append(ptr_out_flag);

m_pADOCmd->CommandText = _bstr_t(pStoreName);//命令字串 

m_pADORec = m_pADOCmd->Execute(&vNULL, &vNULL, adCmdStoredProc);


VretVal = ptr_out_type->Value;
type = VretVal.lVal;

VretVal = ptr_out_flag->Value;
flag = VretVal.lVal;

ptr_insert->Release();
ptr_update->Release();
ptr_tablename->Release();
ptr_sfid->Release();
ptr_out_type->Release();
ptr_out_flag->Release();
}
catch (::_com_error e)
{
_snprintf(sz_msg, sizeof(sz_msg) - 1, "ExecStoredProc error :%s", e.ErrorMessage());
p_MainCwnd->SendMessage(MSG_INFO, 0, (LPARAM)sz_msg);
return false; 
}

return true;

4 个解决方案

#1


用这个 ADO类试试,最下面有调用例子。
或者加异常捕获看是什么错误
try
{
//你的ADO代码
}
catch (_com_error& e)
{
CString strMsg;
strMsg.Format(_T("错误描述:%s\n错误消息%s"), 
(LPCTSTR)e.Description(),
(LPCTSTR)e.ErrorMessage());
AfxMessageBox(strMsg);
}

#2


我是这么干的,但我的存储过程里面木有insert,希望对你有用
VARIANT index; index.vt = VT_I4; index.intVal = 0;
while(m_Command->GetParameters()->GetCount()>0)
m_Command->GetParameters()->raw_Delete(index);
//_ParameterPtr m_Param;
m_Param = m_Command->CreateParameter("",adInteger,adParamInput,sizeof(int),m_TarPage-1);
m_Command->Parameters->Append(m_Param);
m_Param = m_Command->CreateParameter("",adInteger,adParamInput,sizeof(int),m_SkinListCtrl.m_MaxLineInPage);
m_Command->Parameters->Append(m_Param);
m_Param = m_Command->CreateParameter("",adVarChar,adParamInput,m_str_Where_And_Diy_count.GetLength()+1,_variant_t(m_str_Where_And_Diy_count));
m_Command->Parameters->Append(m_Param);
m_Param = m_Command->CreateParameter("",adVarChar,adParamInput,m_str_Where_And_Diy_record.GetLength()+1,_variant_t(m_str_Where_And_Diy_record));
m_Command->Parameters->Append(m_Param);

if(m_SkinListCtrl.m_ppListRecord[0]->GetState()==1)
m_SkinListCtrl.m_ppListRecord[0]->Close();
m_SkinListCtrl.m_ppListRecord[0] = m_Command->Execute(NULL,NULL,adCmdStoredProc); // 获取记录集

#3


你的代码里为什么不加try...catch

#4


引用 3 楼 pipi20091001 的回复:
你的代码里为什么不加try...catch

加了,是在宏里面加的。

#1


用这个 ADO类试试,最下面有调用例子。
或者加异常捕获看是什么错误
try
{
//你的ADO代码
}
catch (_com_error& e)
{
CString strMsg;
strMsg.Format(_T("错误描述:%s\n错误消息%s"), 
(LPCTSTR)e.Description(),
(LPCTSTR)e.ErrorMessage());
AfxMessageBox(strMsg);
}

#2


我是这么干的,但我的存储过程里面木有insert,希望对你有用
VARIANT index; index.vt = VT_I4; index.intVal = 0;
while(m_Command->GetParameters()->GetCount()>0)
m_Command->GetParameters()->raw_Delete(index);
//_ParameterPtr m_Param;
m_Param = m_Command->CreateParameter("",adInteger,adParamInput,sizeof(int),m_TarPage-1);
m_Command->Parameters->Append(m_Param);
m_Param = m_Command->CreateParameter("",adInteger,adParamInput,sizeof(int),m_SkinListCtrl.m_MaxLineInPage);
m_Command->Parameters->Append(m_Param);
m_Param = m_Command->CreateParameter("",adVarChar,adParamInput,m_str_Where_And_Diy_count.GetLength()+1,_variant_t(m_str_Where_And_Diy_count));
m_Command->Parameters->Append(m_Param);
m_Param = m_Command->CreateParameter("",adVarChar,adParamInput,m_str_Where_And_Diy_record.GetLength()+1,_variant_t(m_str_Where_And_Diy_record));
m_Command->Parameters->Append(m_Param);

if(m_SkinListCtrl.m_ppListRecord[0]->GetState()==1)
m_SkinListCtrl.m_ppListRecord[0]->Close();
m_SkinListCtrl.m_ppListRecord[0] = m_Command->Execute(NULL,NULL,adCmdStoredProc); // 获取记录集

#3


你的代码里为什么不加try...catch

#4


引用 3 楼 pipi20091001 的回复:
你的代码里为什么不加try...catch

加了,是在宏里面加的。