如何通过ODBC编程调用存储过程,并且得到存储过程的返回值。

解决方案 »

  1.   

    返回一个记录集:不重载
    CDatabase db;
    db.Open(.....);
    CRecordset rs(&db);
    rs.Open(CRecordset::forwardOnly ,"{call procname 'aaa',bbb',1}");
    if (!rs.IsEOF()){
    ...
    }用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.Close();
    db1.Close();
      

  2.   

    if(!((CSuper_MarketDoc*)GetDocument())->m_db.CanTransact())
    return;
    if(!((CSuper_MarketDoc*)GetDocument())->m_db.BeginTrans())
    return;
    try
    {
    ch="EXEC p_KcspAdd \'"+m_pRsSd->m_sd_bh+"\'";
    ((CSuper_MarketDoc*)GetDocument())->m_db.ExecuteSQL(ch);
    ((CSuper_MarketDoc*)GetDocument())->m_db.CommitTrans();
    }
    catch(CDBException* e)
    {
    ((CSuper_MarketDoc*)GetDocument())->m_db.Rollback();
    AfxMessageBox(e->m_strError);
    e->Delete();
    return;
    }