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 inputParamRFX_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 paramsRFX_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:
存储过程返回值