cplusplus

存储过程返回值

上一篇 / 下一篇  2012-08-21 18:50:17 / 个人分类:转载


可以使用CRecordSet调用存储过程,我已亲自试过 

SQL.Format( "{CALL   Test(%d,%d)} ",Time0,Time1);   
rs.Open(CRecordset::snapshot,SQL,CRecordset::none); 
即可。 
但是如果存储过程没有select语句,程序就会报错,说curser   state   error 
而始终得不到存储过程中的output变量的值!!!! 
各位高手帮小弟一次 
我只有40分了。

用MFC   ODBC 

重载crecordset: 
//chcode.h 
class   chcode   :   public   CRecordset 

public: 
void   Move(   long   nrows,   WORD   wfetchtype   ); 
chcode(CDatabase*   pDatabase   =   NULL); 
DECLARE_DYNAMIC(chcode) 

//   Field/Param   Data 
//{{AFX_FIELD(chcode,   CRecordset) 
long   m_retreturn_value; 
CString   m_newpassword; 
CString   m_oldpassword; 
CString   m_username; 
//}}AFX_FIELD 


//   Overrides 
//   ClassWizard   generated   virtual   function   overrides 
//{{AFX_VIRTUAL(chcode) 
public: 
virtual   CString   GetDefaultConnect();         //   Default   connection   string 
virtual   CString   GetDefaultSQL();         //   Default   SQL   for   Recordset 
virtual   void   DoFieldExchange(CFieldExchange*   pFX);     //   RFX   support 
//}}AFX_VIRTUAL 

//   Implementation 
#ifdef   _DEBUG 
virtual   void   AssertValid()   const; 
virtual   void   Dump(CDumpContext&   dc)   const; 
#endif 
}; 

//{{AFX_INSERT_LOCATION}} 
//   Microsoft   Visual   C++   will   insert   additional   declarations   immediately   before   the   previous   line. 

#endif   //   !defined(AFX_CHCODE_H__FF9F8501_31F2_4794_B697_B7FFB5A15C30__INCLUDED_) 
//chcode.cpp 
//   chcode.cpp   :   implementation   file 
// 

#include   "stdafx.h " 
#include   "chcode.h " 

#ifdef   _DEBUG 
#define   new   DEBUG_NEW 
#undef   THIS_FILE 
static   char   THIS_FILE[]   =   __FILE__; 
#endif 

///////////////////////////////////////////////////////////////////////////// 
//   chcode 
void   AFXAPI   RFX_Textout(CFieldExchange   *   pfx,   LPCTSTR   szname, 
CString&   value,   int   nmaxlength,   int   ncolumntype,   short   nscale); 
IMPLEMENT_DYNAMIC(chcode,   CRecordset) 

chcode::chcode(CDatabase*   pdb) 
:   CRecordset(pdb) 

//{{AFX_FIELD_INIT(chcode) 
m_oldpassword= " "; 
m_newpassword= " "; 
m_username= " ";
//}}AFX_FIELD_INIT 
m_nDefaultType   =   snapshot; 
m_nParams=4;   } 


CString   chcode::GetDefaultConnect() 

return   _T( "ODBC;DSN= "); 


CString   chcode::GetDefaultSQL() 

return   _T( " "); 


void   chcode::DoFieldExchange(CFieldExchange*   pFX) 

//{{AFX_FIELD_MAP(chcode)
pFX-> SetFieldType(CFieldExchange   ::outputParam);   //set   the   field   type   to outputParam   for   the   return   value 
RFX_Long(pFX,   _T( "return_value "),   m_retreturn_value);   //bind   the   return   value to   the   variable   
pFX-> SetFieldType(CFieldExchange   ::inputParam);   //reset   the   field   type   to inputParam
RFX_Text(pFX,   "@old ",   m_oldpassword);//,255,SQL_CHAR,0);
RFX_Text(pFX,   "@new ",   m_newpassword);//,255,SQL_CHAR,0);   //call the   new   rfx_Text   to   get   the   character   output   params
RFX_Text(pFX,   "@loginame ",   m_username);//,255,SQL_CHAR,0); 
//}}AFX_FIELD_MAP 


///////////////////////////////////////////////////////////////////////////// 
//   chcode   diagnostics 

#ifdef   _DEBUG 
void   chcode::AssertValid()   const 

CRecordset::AssertValid(); 


void   chcode::Dump(CDumpContext&   dc)   const 

CRecordset::Dump(dc); 

#endif   //_DEBUG 
//Move(long   nRows,   WORD   wFetchType) 
void   chcode::Move(long   nrows,   WORD   wfetchtype) 

if   (m_nFields) 
CRecordset   ::Move(nrows,   wfetchtype); 
else 
m_bBOF   =   m_bEOF   =   true; 



调用: 

CDatabase   db1;
s1.Format( "ODBC;UID=sa;PWD=%s ", " "); 
db1.Open( "report ",false,false,s1);
chcode   chrs(&db1); 
//CRecordset   rs(&db1); 
chrs.m_newpassword=in.m1; 
chrs.m_oldpassword=s3; 
chrs.m_username= "report ";
chrs.Open(   AFX_DB_USE_DEFAULT_TYPE   ,_T( "{?=CALL   sp_password(?,?,?)} "));
//chrs.Open(AFX_DB_USE_DEFAULT_TYPE, "{call   sp_password( 'report ', 'report ', 'report ')} "); 
                                      //chrs.m_retreturn_value;这就是返回值 
chrs.Close(); 
db1.Close(); 

你也可以去看看下面的例子: 
http://www.codeproject.com/database/mssqltutorial.asp 
http://www.codeproject.com/database/MyRecordset.asp 
http://www.codeproject.com/database/spcw.asp


派生Crecordset,在其中设置输入和输出变量。

例:

class Cabc : public CRecordset

{

...

}

CRecordset中的m_nParams设置成参数的个数。包括存储过程的所有参数。

ODBC的执行存储过程写法:

{[?=]call procedure_name[([parameter][,[parameter]]...)]}

重载CRecordSet::DoFieldExchange(CFieldExchange* pFX)

例:

void Cabc::DoFieldExchange(CFieldExchange* pFX)
{

 pFX->SetFieldType(CFieldExchange::inputParam);//指定参数类型,为输入参数。注意存储过程的返回值是输出参数。SetFieldType设置为输入,在没有重新调用SetFieldType来改变参数类型时,一直就是输入参数。
 RFX_Text(pFX, _T("@abc"), m_p1);
 pFX->SetFieldType(CFieldExchange::outputParam);//指定参数类型为输出参数
 RFX_Text(pFX, _T("@def"), m_p2);

}

在函数里设置参数时,一定要按存储过程里面的参数顺序来填写。

调用CRecordset.Open来执行存储过程。

执行完成后,输出参数并没有返回到定义的变量中,需要执行CRecordset::FlushResultSet()

例:

while(Cabc.FlushResultSet());

完成后,就接收到了所有参数。


http://blog.sina.com.cn/s/blog_5e091aba0100ci67.html


TAG: 存储过程返回值

 

评分:0

我来说两句

Open Toolbar