能否不重载CRecordSet类,用MFC ODBC调用带返回值和参数的存储过程

 

能否不重载CRecordSet类,用MFC ODBC调用带返回值和参数的存储过程

楼主casale(无三) 2005-06-28 18:40:16 在 VC/MFC / 数据库 提问

重载CRecordSet的方法本人已经知道,但我要调用的类似存储过程有好多个,不想一个个重载,请高手指教!还有,只能用MFC   ODBC,其他方法就不要了。 问题点数:50、回复次数:6Top

1 楼ok1234567(ok1234567)回复于 2005-06-28 19:40:23 得分 50

如下代码供你参考:  
  CREATE   PROCEDURE   [cp_man_work_del]  
  @wiid int  
   
  AS  
   
  SET   NOCOUNT   ON  
  /*  
  [man_work]   (  
  [wiid]   [int]   IDENTITY   (1,   1)   NOT   NULL   ,  
  [wcmode]   [char]   (1)   NOT   NULL    
  */  
  DECLARE   @cmode   char(1)  
  SELECT   @cmode=wcmode   FROM   man_work   WHERE   wiid=@wiid  
   
  IF   @cmode   IS   NULL RETURN   -2  
  IF   @cmode   =   'C' RETURN   -3  
   
  DELETE   man_work   WHERE   wiid=@wiid  
  IF   @@ERROR   <>   0   RETURN   -9  
   
  RETURN   @wiid  
  //存储过程结束  
  C++   程序要点  
  #include   <afxdb.h>  
   
  BOOL   CWorkPage::DoDelete()  
  {  
  UpdateData();  
  //------------------------------------  
  SQLRETURN   retcode;  
  SQLHENV   m_henv;  
  SQLHDBC   m_hdbc;  
  retcode   =   SQLAllocHandle(SQL_HANDLE_ENV,SQL_NULL_HANDLE,&m_henv);  
  if   (retcode   !=   SQL_SUCCESS   &&   retcode   !=   SQL_SUCCESS_WITH_INFO)    
  {    
  AfxMessageBox("数据库环境句柄分配错误。");  
  return   FALSE;  
  }  
  retcode   =   SQLSetEnvAttr(m_henv,   SQL_ATTR_ODBC_VERSION,   (void*)SQL_OV_ODBC3,   0);  
  if   (retcode   !=   SQL_SUCCESS   &&   retcode   !=   SQL_SUCCESS_WITH_INFO)    
  {    
  AfxMessageBox("数据库环境句柄设置错误。");  
  return   FALSE;  
  }  
   
  retcode   =SQLAllocHandle(SQL_HANDLE_DBC,m_henv,&m_hdbc);  
  if   (retcode   !=   SQL_SUCCESS   &&   retcode   !=   SQL_SUCCESS_WITH_INFO)  
  {  
  AfxMessageBox("数据库连接句柄分配错误。");  
  return   FALSE;  
  }  
  //Set   login   timeout   to   20   seconds.    
  SQLSetConnectAttr(m_hdbc,   SQL_LOGIN_TIMEOUT,   (void*)20,   0);  
  //   Connect   to   data   source    
  retcode   =   SQLConnect(m_hdbc,(SQLCHAR*)   m_szDSN,   SQL_NTS,    
  (SQLCHAR*)   m_szUID,   SQL_NTS,    
  (SQLCHAR*)   m_szPWD,   SQL_NTS);  
  if   (retcode   !=   SQL_SUCCESS   &&   retcode   !=   SQL_SUCCESS_WITH_INFO)  
  {  
  AfxMessageBox("数据库连接错误。");  
  return   FALSE;  
  }  
   
  SQLHSTMT hstmt =   SQL_NULL_HSTMT;  
  if(SQLAllocHandle(SQL_HANDLE_STMT,   m_hdbc,   &hstmt)!=SQL_SUCCESS)  
  {  
  AfxMessageBox("数据库操作句柄分配错误。");  
  return   FALSE;  
  }  
   
  SQLHSTMT hstmt =   SQL_NULL_HSTMT;  
  SQLINTEGER siRetCode,cbRet;  
  siRetCode =0;  
  if(SQLAllocHandle(SQL_HANDLE_STMT,   m_hdbc,   &hstmt)!=SQL_SUCCESS)  
  {  
  MessageBox("数据库操作句柄分配错误,操作失败。");  
  return   FALSE;  
  }  
  m_pCatvView->m_pMainWindow->m_pApp->SetDBState();  
   
  char   szSql[96];  
  sprintf(szSql,  
  "{?=CALL   catv.dbo.cp_man_work_del(%d)}",  
  m_iCurID);  
  retcode   =SQLBindParameter(hstmt,    
                                                                          1,    
  SQL_PARAM_OUTPUT,  
  SQL_C_SLONG,    
  SQL_INTEGER,    
  0,    
  0,    
  &siRetCode,    
  0,    
  &cbRet);  
  if   (!(retcode   ==   SQL_SUCCESS   ||   retcode   ==   SQL_SUCCESS_WITH_INFO))    
  {  
  SQLFreeHandle(SQL_HANDLE_STMT,   hstmt);  
  MessageBox("数据库参数绑定错误。","提示");  
  return   FALSE;  
  }  
  retcode   =SQLExecDirect(hstmt,(unsigned   char   *)szSql,SQL_NTS);  
  SQLFreeHandle(SQL_HANDLE_STMT,   hstmt);  
  m_pCatvView->m_pMainWindow->m_pApp->SetDBState(TRUE);  
  if   (!(retcode   ==   SQL_SUCCESS   ||   retcode   ==   SQL_SUCCESS_WITH_INFO)   ||   siRetCode   ==   -9)    
  {  
  MessageBox("数据库内部错误,操作未完成。");  
  return   FALSE;  
  }  
   
  if(siRetCode   <   0)  
  {  
  switch(siRetCode)  
  {  
  case   -2:  
  MessageBox("任务记录不存在,可能刚被删除。");  
  break;  
  case   -3:  
  MessageBox("任务已经完成,不能删除。");  
  break;  
  default:  
  MessageBox("未知的数据库内部错误,操作未完成。");  
  }  
  return   FALSE;    
  }  
   
  return   TRUE;  
  }  
   
  以上为要点,是从我的程序里拷贝的  
  变量不完整,看变量名应该就明白了  
  另外,在程序中,  
  m_henv只建一个  
  m_hdbc   有限个(初始化为连接池),通过一定的同步机制,从连接池中获取,这样可以提高程序的效率  
   
   
   
  Top

2 楼ok1234567(ok1234567)回复于 2005-06-28 19:52:54 得分 0

如下为一个没有改动的delete方法,  
  上面拷贝的代码有重复,对照参考,应该可以完成的设计目标:)  
   
  BOOL   CWorkPage::DoDelete()  
  {  
  UpdateData();  
  //------------------------------------  
  if(!m_pCatvView->m_pMainWindow->m_pApp->GetDBState())//获得连接句炳,全部程序共用一个  
  {  
  MessageBox("数据库忙,等会再试。","提示");  
  return   FALSE;  
  }  
  SQLRETURN retcode;  
  SQLHSTMT hstmt =   SQL_NULL_HSTMT;  
  SQLINTEGER siRetCode,cbRet;  
  siRetCode =0;  
  if(SQLAllocHandle(SQL_HANDLE_STMT,   m_pCatvView->m_pMainWindow->m_pApp->m_hdbc,   &hstmt)!=SQL_SUCCESS)  
  {  
  MessageBox("数据库操作句柄分配错误,操作失败。");  
  return   FALSE;  
  }  
  m_pCatvView->m_pMainWindow->m_pApp->SetDBState();//设置连接句柄被使用标志  
   
  char   szSql[96];  
  sprintf(szSql,  
  "{?=CALL   catv.dbo.cp_man_work_del(%d)}",  
  m_iCurID);  
  retcode   =SQLBindParameter(hstmt,    
  1,    
  SQL_PARAM_OUTPUT,  
  SQL_C_SLONG,    
  SQL_INTEGER,    
  0,    
  0,    
  &siRetCode,    
  0,    
  &cbRet);  
  if   (!(retcode   ==   SQL_SUCCESS   ||   retcode   ==   SQL_SUCCESS_WITH_INFO))    
  {  
  SQLFreeHandle(SQL_HANDLE_STMT,   hstmt);  
  m_pCatvView->m_pMainWindow->m_pApp->SetDBState(TRUE);  
  MessageBox("数据库参数绑定错误。","提示");  
  return   FALSE;  
  }  
  retcode   =SQLExecDirect(hstmt,(unsigned   char   *)szSql,SQL_NTS);  
  SQLFreeHandle(SQL_HANDLE_STMT,   hstmt);  
  m_pCatvView->m_pMainWindow->m_pApp->SetDBState(TRUE);//清除使用标志  
  if   (!(retcode   ==   SQL_SUCCESS   ||   retcode   ==   SQL_SUCCESS_WITH_INFO)   ||   siRetCode   ==   -9)    
  {  
  MessageBox("数据库内部错误,操作未完成。");  
  return   FALSE;  
  }  
   
  if(siRetCode   <   0)  
  {  
  switch(siRetCode)  
  {  
  case   -2:  
  MessageBox("任务记录不存在,可能刚被删除。");  
  break;  
  case   -3:  
  MessageBox("任务已经完成,不能删除。");  
  break;  
  default:  
  MessageBox("未知的数据库内部错误,操作未完成。");  
  }  
  return   FALSE;    
  }  
   
  m_lst.DeleteItem((int)m_posCur-1);  
   
  DoClear();  
  return   TRUE;  
  }Top

3 楼ok1234567(ok1234567)回复于 2005-06-28 20:04:10 得分 0

参数的返回:  
   
  CREATE   PROCEDURE   [cp_get_topic_search_page]  
  @itotal   int   OUTPUT,  
  @str   varchar(8000)   OUTPUT,  
  @iindex int  
  .....  
  SELECT   @itotal=COUNT(1)   FROM   ....  
  .....  
  RETURN   0  
   
   
                    ......  
  strcpy(pDB->szSql,"{?=CALL   ");  
  strcat(pDB->szSql,szDBName);  
  strcat(pDB->szSql,".dbo.cp_get_forum_topic_search_page(?,?,20,");  
  .......  
   
  //   --   begin   to   bind   3   parameters   ----  
  retcode   =SQLBindParameter(hstmt,    
  1,    
  SQL_PARAM_OUTPUT,  
  SQL_C_SLONG,    
  SQL_INTEGER,    
  0,    
  0,    
  &(pDB->siRetCode),    
  0,    
  &(pDB->cb[0]));  
  if   (!(retcode   ==   SQL_SUCCESS   ||   retcode   ==   SQL_SUCCESS_WITH_INFO))    
  {  
  SQLFreeHandle(SQL_HANDLE_STMT,   hstmt);  
  pDB->bIdle=TRUE;  
  MessGen(pCtxt,pDataWeb->m_szName,CMessPub::BusyRetry,2);  
  return   ;  
  }  
  retcode   =SQLBindParameter(hstmt,    
  2,    
  SQL_PARAM_OUTPUT,  
  SQL_C_SLONG,    
  SQL_INTEGER,    
  0,    
  0,    
  &(pDB->siTotal),    
  0,    
  &(pDB->cb[1]));  
  if   (!(retcode   ==   SQL_SUCCESS   ||   retcode   ==   SQL_SUCCESS_WITH_INFO))    
  {  
  SQLFreeHandle(SQL_HANDLE_STMT,   hstmt);  
  pDB->bIdle=TRUE;  
  MessGen(pCtxt,pDataWeb->m_szName,CMessPub::BusyRetry,2);  
  return   ;  
  }  
  retcode   =SQLBindParameter(hstmt,    
  3,    
  SQL_PARAM_OUTPUT,  
  SQL_C_CHAR,    
  SQL_CHAR,    
  8000,    
  0,    
  pDB->scStr,    
  8002,    
  &(pDB->cb[2]));  
  if   (!(retcode   ==   SQL_SUCCESS   ||   retcode   ==   SQL_SUCCESS_WITH_INFO))    
  {  
  SQLFreeHandle(SQL_HANDLE_STMT,   hstmt);  
  pDB->bIdle=TRUE;  
  MessGen(pCtxt,pDataWeb->m_szName,CMessPub::BusyRetry,2);  
  return   ;  
  }  
  //--   bind   parameters   end   ---  
   
   
  SQLExecDirect后,这些参数就可以用了Top

4 楼casale(无三)回复于 2005-06-28 20:18:52 得分 0

一二三楼的老兄,你的代码用的是ODBC   API吧!这个我也看过啊,还是很不方便的啊,比重载CRecordSet好不到哪啊!我就是不想太麻烦啊,就没办法直接用MFC   ODBC吗Top

5 楼ok1234567(ok1234567)回复于 2005-06-28 21:55:39 得分 0

MFC   封装的database类运行效率是很低的  
  我用过一段时间,忍受不了他的效率,所以后来都用ODBC   API了  
  我对MFC   封装的database类只用了一年多  
  没有找到其直接回传参数的接口  
   
  ODBC   API看起来复杂,其实不难  
  可以自己封装几个类,开发效率不是问题  
   
  Top

6 楼pieapple()回复于 2005-07-03 02:11:57 得分 0

请问楼主能不能把那个CRecordSet重载的方法贴一下啊?   我最近也遇到类似的问题,   谢谢啊!Top

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值