Open and Close Methods Example (VC++)
This example uses the Open and Close methods on both Recordset and Connection objects that have been opened.// BeginOpenCpp
#import "C:\Program Files\Common Files\System\ADO\msado15.dll"     no_namespace rename("EOF", "EndOfFile")#include <oledb.h>
#include <stdio.h>
#include <conio.h>
#include "OpenX.h"// Function declarations
inline void TESTHR(HRESULT x) {if FAILED(x) _com_issue_error(x);};
void OpenX(void);
void PrintProviderError(_ConnectionPtr pConnection);
void PrintComError(_com_error &e);///////////////////////////////////////////////////////////
//                                                       //
//      Main Function                                    //
//                                                       //
///////////////////////////////////////////////////////////void main()
{
    if(FAILED(::CoInitialize(NULL)))
        return;    OpenX();    ::CoUninitialize();
}///////////////////////////////////////////////////////////
//                                                       //
//               OpenX Function                          //
//                                                       //
///////////////////////////////////////////////////////////void OpenX(void)
{
    // Define ADO object pointers.
    // Initialize pointers on define.
    // These are in the ADODB::  namespace
     _RecordsetPtr    pRstEmployee  = NULL;
     _ConnectionPtr pConnection    = NULL;    // Define string variables.
    _bstr_t strCnn("Provider=sqloledb;Data Source=MyServer;"
        "Initial Catalog=pubs;User Id=sa;Password=;");    // Define Other Variables.
    HRESULT  hr = S_OK;
    IADORecordBinding   *picRs  = NULL;  // Interface Pointer declared.
    CEmployeeRs emprs;       // C++ Class object
    DBDATE varDate;    try
    {
        // open connection and record set
        TESTHR(pConnection.CreateInstance(__uuidof(Connection)));
        pConnection->Open(strCnn,"","",adConnectUnspecified);        TESTHR(pRstEmployee.CreateInstance(__uuidof(Recordset)));
        pRstEmployee->Open("Employee", 
            _variant_t((IDispatch *)pConnection,true), adOpenKeyset,
            adLockOptimistic, adCmdTable);        // Open an IADORecordBinding interface pointer which we'll 
        // use for Binding Recordset to a class.
        TESTHR(pRstEmployee->QueryInterface(
            __uuidof(IADORecordBinding),(LPVOID*)&picRs));        //Bind the Recordset to a C++ Class here.
        TESTHR(picRs->BindToRecordset(&emprs));        // Assign the first employee record's hire date
        // to a variable, then change the hire date.
        varDate = emprs.m_sze_hiredate;
        printf("\nOriginal data\n");
        printf("\tName - Hire Date\n");
        printf("  %s  %s - %d/%d/%d\n\n",
            emprs.le_fnameStatus == adFldOK ? 
            emprs.m_sze_fname : "<NULL>",
            emprs.le_lnameStatus == adFldOK ? 
            emprs.m_sze_lname : "<NULL>",
            emprs.le_hiredateStatus == adFldOK ? 
            emprs.m_sze_hiredate.month : 0,
            emprs.le_hiredateStatus == adFldOK ? 
            emprs.m_sze_hiredate.day : 0,
            emprs.le_hiredateStatus == adFldOK ? 
            emprs.m_sze_hiredate.year : 0);         emprs.m_sze_hiredate.year=1900;
        emprs.m_sze_hiredate.month=1;
        emprs.m_sze_hiredate.day=1;
        picRs->Update(&emprs);        printf("\nChanged data\n");
        printf("\tName - Hire Date\n");
        printf("  %s %s - %d/%d/%d\n\n",
            emprs.le_fnameStatus == adFldOK ? 
            emprs.m_sze_fname : "<NULL>",
            emprs.le_lnameStatus == adFldOK ? 
            emprs.m_sze_lname : "<NULL>",
            emprs.le_hiredateStatus == adFldOK ? 
            emprs.m_sze_hiredate.month : 0,
            emprs.le_hiredateStatus == adFldOK ? 
            emprs.m_sze_hiredate.day : 0,
            emprs.le_hiredateStatus == adFldOK ? 
            emprs.m_sze_hiredate.year : 0);         // Requery Recordset and reset the hire date.
        pRstEmployee->Requery(adOptionUnspecified);
        // Open an IADORecordBinding interface pointer which we'll 
        // use for Binding Recordset to a class.
        TESTHR(pRstEmployee->QueryInterface(
            __uuidof(IADORecordBinding),(LPVOID*)&picRs));        // Rebind the Recordset to a C++ Class here.
        TESTHR(picRs->BindToRecordset(&emprs));
        emprs.m_sze_hiredate = varDate;
        picRs->Update(&emprs);
        printf("\nData after reset\n");
        printf("\tName - Hire Date\n");
        printf("  %s %s - %d/%d/%d",emprs.le_fnameStatus == adFldOK ? 
            emprs.m_sze_fname : "<NULL>",
            emprs.le_lnameStatus == adFldOK ? 
            emprs.m_sze_lname : "<NULL>",
            emprs.le_hiredateStatus == adFldOK ? 
            emprs.m_sze_hiredate.month : 0,
            emprs.le_hiredateStatus == adFldOK ? 
            emprs.m_sze_hiredate.day : 0,
            emprs.le_hiredateStatus == adFldOK ? 
            emprs.m_sze_hiredate.year : 0);         // Clean up objects before exit.
        pRstEmployee->Close();
        pConnection->Close();
    }    catch(_com_error &e)
    {
        // Notify the user of errors if any.
        // Pass a connection pointer accessed from the Connection.
        PrintProviderError(pConnection);
        PrintComError(e);
    }
}///////////////////////////////////////////////////////////
//                                                       //
//      PrintProviderError Function                      //
//                                                       //
///////////////////////////////////////////////////////////void PrintProviderError(_ConnectionPtr pConnection)
{
    // Print Provider Errors from Connection object.
    // pErr is a record object in the Connection's Error collection.
    ErrorPtr    pErr  = NULL;    if( (pConnection->Errors->Count) > 0)
    {
        long nCount = pConnection->Errors->Count;
        // Collection ranges from 0 to nCount -1.
        for(long i = 0;i < nCount;i++)
        {
            pErr = pConnection->Errors->GetItem(i);
            printf("\t Error number: %x\t%s", pErr->Number,
                pErr->Description);
        }
    }
}///////////////////////////////////////////////////////////
//                                                       //
//      PrintComError Function                           //
//                                                       //
///////////////////////////////////////////////////////////void PrintComError(_com_error &e)
{
   _bstr_t bstrSource(e.Source());
   _bstr_t bstrDescription(e.Description());    // Print COM errors. 
   printf("Error\n");
   printf("\tCode = %08lx\n", e.Error());
   printf("\tCode meaning = %s\n", e.ErrorMessage());
   printf("\tSource = %s\n", (LPCSTR) bstrSource);
   printf("\tDescription = %s\n", (LPCSTR) bstrDescription);
}
// EndOpenCppOpenX.h:// BeginOpenH
#include "icrsint.h"// This Class extracts only fname,lastname and 
// hire_date from employee table
class CEmployeeRs : public CADORecordBinding
{BEGIN_ADO_BINDING(CEmployeeRs)
    
    // Column fname is the 2nd field in the table   
   ADO_VARIABLE_LENGTH_ENTRY2(2, adVarChar, m_sze_fname, 
         sizeof(m_sze_fname), le_fnameStatus, FALSE)
    
    // Column lname is the 4th field in the table.
   ADO_VARIABLE_LENGTH_ENTRY2(4, adVarChar, m_sze_lname, 
         sizeof(m_sze_lname), le_lnameStatus, FALSE)    // Column hiredate is the 8th field in the table.
   ADO_VARIABLE_LENGTH_ENTRY2(8, adDBDate,m_sze_hiredate, 
         sizeof(m_sze_hiredate), le_hiredateStatus, TRUE)
   
END_ADO_BINDING()public:
   CHAR        m_sze_fname[21];
   ULONG    le_fnameStatus;
   CHAR        m_sze_lname[31];
   ULONG    le_lnameStatus;
   DBDATE    m_sze_hiredate;
   ULONG    le_hiredateStatus;
};
// EndOpenH

解决方案 »

  1.   

    odbc api, ado, dao都可以
      

  2.   

    jiangsheng(蒋晟):
      看不懂,能讲讲吗?
      

  3.   

                                         
                                    我也来贴一个呀,别闲长呀
    // database.cpp -- 
    ////
    // contains the functions that deal directly with DAODatabase
    // creation, opening and closing:
    //
    // void closeDatabase(CDaoDatabase **ppDatabase);
    //
    // int openDatabase(CDaoDatabase **ppDatabase, CString fileName,
    //                BOOL bReportNoOpen = TRUE);
    //
    // BOOL createDatabase(CDaoDatabase **ppDatabase, CString fileName,
    //                int dwOptions = 0);#include "stdafx.h"
    #include "database.h"// close the database and destruct it
    // IN/OUT:: ppDatabase--pointer to pointer to database to close and
    // destruct
    void closeDatabase(CDaoDatabase **ppDatabase)
    {
    // only process if the database object exists
    if (*ppDatabase != NULL)
    {
    if ((*ppDatabase)->IsOpen())
    (*ppDatabase)->Close(); // closing doesn't delete the object
    delete *ppDatabase;
    *ppDatabase = NULL;
    }
    }// open the database from a file (close if necessary)
    // IN/OUT: ppDatabase--pointer to pointer to database object
    // IN: fileName--name of .mdb file to open
    // IN: bReportNoOpen--TRUE by default, if true, if open fails
    //     because the specified MDB file doesn't exist, report that
    //     fact to the user.  Note: other errors are reported always
    // RETURN: 1 if success, 0 if non-fatal failure, -1 if fatal failure
    int openDatabase(CDaoDatabase **ppDatabase, CString fileName,
      BOOL bReportNoOpen /* = TRUE */)
    {
    // initialize success indicator
    int nReturnCode = 1; // close and delete if necessary
    if (*ppDatabase != NULL)
    {
    if ((*ppDatabase)->IsOpen())
    closeDatabase(ppDatabase);
    delete *ppDatabase;
    } // construct new database
    *ppDatabase = new CDaoDatabase; // failed to allocate
    if (ppDatabase == NULL)
    return -1; // fatal error // now open the database object with error checking try
    {
    (*ppDatabase)->Open(fileName);
    }
    catch (CDaoException *e)
    {
    // special case--couldn't find the file, so it may be because
    // user specified a new file to open
    if (e->m_pErrorInfo->m_lErrorCode == 3024)
    {
    if (bReportNoOpen)
    {
    // create a message to display
    CString message = _T("打开数据库失败,出现异常:");
    message += e->m_pErrorInfo->m_strDescription; // output status
    AfxMessageBox(message);
    } // indicate failure but not fatal
    nReturnCode = 0;
    }
    else // other type of DAO exception--always report
    {
    // create a message to display
    CString message = _T("打开数据库失败,出现异常:");
    message += e->m_pErrorInfo->m_strDescription; // output status
    AfxMessageBox(message); // indicate fatal error
    nReturnCode = -1;
    } // not rethrowing, so delete exception
    e->Delete(); delete *ppDatabase;
    *ppDatabase = NULL;
    }
    catch (CMemoryException *e)
    {
    // output status
    AfxMessageBox(_T("Failed to open database--Memory exception thrown.")); // not rethrowing, so delete exception
    e->Delete(); delete *ppDatabase;
    *ppDatabase = NULL; // indicate fatal error
    nReturnCode = -1;
    } return nReturnCode;
    }// create the database file (close any open database)
    // IN/OUT: ppDatabase--pointer to pointer to database object
    // IN: fileName--name of .mdb file to open
    // IN: dwOptions--info like version and encryption settings
    //     0 by default
    // RETURN: TRUE if success, FALSE if failure
    BOOL createDatabase(CDaoDatabase **ppDatabase, CString fileName,
      int dwOptions /* = 0 */)
    {
    // initialize success indicator
    BOOL bSuccess = TRUE; // close and delete if necessary
    if (*ppDatabase != NULL)
    {
    if ((*ppDatabase)->IsOpen())
    closeDatabase(ppDatabase);
    delete *ppDatabase;
    } // construct new database
    *ppDatabase = new CDaoDatabase; // failed to allocate
    if (ppDatabase == NULL)
    return FALSE; // error // now create the database object with error checking
    try
    {
    // default language specified
    (*ppDatabase)->Create(fileName, dbLangGeneral, dwOptions);
    }
    catch (CDaoException *e)
    {
    // create a message to display
    CString message = _T("创建数据库失败,出现异常:");
    message += e->m_pErrorInfo->m_strDescription; // output status
    AfxMessageBox(message); // not rethrowing, so delete exception
    e->Delete(); delete *ppDatabase;
    *ppDatabase = NULL; // failure
    bSuccess = FALSE;
    }
    catch (CMemoryException *e)
    {
    // output status
    AfxMessageBox(_T("Failed to create database--Memory exception thrown.")); // not rethrowing, so delete exception
    e->Delete(); delete *ppDatabase;
    *ppDatabase = NULL; // failure
    bSuccess = FALSE;
    } return bSuccess;
    }#include "stdafx.h"
    #include "dbcomfun.h"
    #include "database.h"
    #include "crack.h"//extern CString StandardLibPath;
    void OpenClassTable(CDaoDatabase * m_st_data,CDaoRecordset &rs,CString tablename)
    {
    if(!m_st_data->IsOpen())
    // openDatabase(&m_st_data,StandardLibPath);
    CString strSelect = "Select * From ["+tablename+"]";
    // rs.Open(dbOpenDynaset,strSelect);
    if(rs.GetRecordCount()!=0)
    rs.MoveFirst();
    }CString GetDbVaule(CDaoRecordset &rs, int number)
    {
    COleVariant var;
    //level
    var = rs.GetFieldValue(number);
    CString strtemp = CCrack::strVARIANT(var);
    return strtemp;
    }void DisplayDaoException(CDaoException* e)
    {
    CString strMsg;
    if (e->m_pErrorInfo!=NULL)
    {
    strMsg.Format(
    _T("%s   (%d)\n\n")
    _T("Would you like to see help?"),
    (LPCTSTR)e->m_pErrorInfo->m_strDescription,
    e->m_pErrorInfo->m_lErrorCode); if (AfxMessageBox(strMsg, MB_YESNO) == IDYES)
    {
    WinHelp(GetDesktopWindow(),
    e->m_pErrorInfo->m_strHelpFile,
    HELP_CONTEXT,
    e->m_pErrorInfo->m_lHelpContext);
    }
    }
    else
    {
    strMsg.Format(
    _T("ERROR:CDaoException\n\n")
    _T("SCODE_CODE      =%d\n")
    _T("SCODE_FACILITY  =%d\n")
    _T("SCODE_SEVERITY  =%d\n")
    _T("ResultFromScode =%d\n"),
    SCODE_CODE      (e->m_scode),
    SCODE_FACILITY  (e->m_scode),
    SCODE_SEVERITY  (e->m_scode),
    ResultFromScode (e->m_scode));
    AfxMessageBox(strMsg);
    }
    }BOOL IsExistentTable(CDaoDatabase *pDatabase, CString strTableName)
    {
    // if the database is non-existent, then the answer is obvious
    if (pDatabase == NULL)
    return FALSE; // initialize status indicator
    BOOL bDuplicateTableName = TRUE; // see if there is a table by this name already--duplicate
    // named tables are not accepted
    CDaoTableDefInfo tableInfo; // only needed for the call // MFC exception handler macros used
    TRY
    {
    // this call will throw an exception if there is no
    // table by the specified name--test for duplication
    pDatabase->GetTableDefInfo(strTableName, tableInfo);
    }
    CATCH (CDaoException, e)
    {
    // if this is an 'Item not found' exception, we are
    // cleared to create the table -- else this is
    // a duplicate tablename and we got another exception
    // which is irrelevant for our purposes
    if (e->m_pErrorInfo->m_lErrorCode == 3265)
    bDuplicateTableName = FALSE;
    }
    AND_CATCH (CMemoryException, e)
    {
    // do nothing
    ;
    }
    END_CATCH return bDuplicateTableName;
    }BOOL createNewTableDef(CDaoDatabase * pDatabase,
    CDaoTableDef **ppTableDef,
    CString strTableName)
    {
    // if the database is non-existent, then the answer is obvious
    if (pDatabase == NULL)
    return FALSE; // check for existing table with this name just to be safe
    if (IsExistentTable(pDatabase, strTableName))
    {
    AfxMessageBox(_T("A table by that name already exists.")); // return FALSE since can't create duplicate table
    return FALSE;
    } // initialize creation failure indicator
    BOOL bCreateFailed = FALSE; // construct tabledef
    *ppTableDef = new CDaoTableDef(pDatabase); // failed to allocate so exit
    if ((*ppTableDef) == NULL)
    return FALSE; // no duplication, so create the tabledef if possible
    TRY
    {
    (*ppTableDef)->Create(strTableName);
    }
    CATCH (CDaoException, e)
    {
    // construct a meaningful message
    CString strMessage = _T("Couldn't create tabledef--Exception: ");
    strMessage += e->m_pErrorInfo->m_strDescription; AfxMessageBox(strMessage); // indicate failure
    bCreateFailed = TRUE; // delete the tabledef on failure
    if (*ppTableDef != NULL)
    {
    delete *ppTableDef;
    *ppTableDef = NULL;
    }
    }
    AND_CATCH (CMemoryException, e)
    {
    // output status
    AfxMessageBox(_T("Failed to create tabledef--Memory exception thrown.")); // indicate failure
    bCreateFailed = TRUE; // delete the tabledef on failure
    if (*ppTableDef != NULL)
    {
    delete *ppTableDef;
    *ppTableDef = NULL;
    }
    }
    END_CATCH // return TRUE if creation succeeds
    return (!bCreateFailed);
    }BOOL createNewField(CDaoTableDef *pTableDef, CDaoFieldInfo *pFieldInfo)
    {
    // if the tabledef is non-existent, then the answer is obvious
    if (pTableDef == NULL)
    return FALSE; // check for existing field with this name just to be safe
    if (IsExistentField(pTableDef, pFieldInfo->m_strName))
    {
    AfxMessageBox(_T("A field by that name already exists.")); // return FALSE since can't create duplicate field
    return FALSE;
    } // initialize failure indicators
    BOOL bCreateFailed = FALSE; // create a field with the specified properties
    // it is automatically appended to field collection
    // of the tabledef
    TRY
    {
    pTableDef->CreateField(*pFieldInfo);
    }
    CATCH (CDaoException, e)
    {
    // construct a meaningful message
    CString message = _T("Couldn't create field--Exception: ");
    message += e->m_pErrorInfo->m_strDescription; // display message
    AfxMessageBox(message); // indicate failure
    bCreateFailed = TRUE;
    }
    AND_CATCH (CMemoryException, e)
    {
    AfxMessageBox(_T("Failed to create field--Memory exception thrown.")); // indicate failure
    bCreateFailed = TRUE;
    }
    END_CATCH // return TRUE if creation succeeds
    return (!bCreateFailed);
    }
    BOOL appendTableDef(CDaoDatabase *pDatabase, CDaoTableDef *pTableDef)
    {
    // if the database is non-existent, then the answer is obvious
    if (pDatabase == NULL)
    return FALSE; // initialize success indicator
    BOOL bSuccess = TRUE; // append the tabledef to the collection
    TRY
    {
    pTableDef->Append();
    }
    CATCH (CDaoException, e)
    {
    // construct informative message
    CString strMessage = _T("Couldn't append TableDef--Exception: ");
    strMessage += e->m_pErrorInfo->m_strDescription; // output status
    AfxMessageBox(strMessage); // failure
    bSuccess = FALSE;
    }
    AND_CATCH (CMemoryException, e)
    {
    // output status
    AfxMessageBox(_T("Failed to append tabledef--Memory exception thrown.")); // failure
    bSuccess = FALSE;
    }
    END_CATCH // return status
    return bSuccess;
    }
    BOOL deleteField(CDaoTableDef *pTableDef, CString strFieldName)
    {
    // if the tabledef is non-existent, then the answer is obvious
    if (pTableDef == NULL)
    return FALSE; // initialize success indicator
    BOOL bSuccess = TRUE; // MFC exception handler macros used
    TRY
    {
    // this call will throw an exception if there is no
    // field by the specified name--test for duplication
    pTableDef->DeleteField(strFieldName);
    }
    CATCH (CDaoException, e)
    {
    CString strMessage = _T("Couldn't delete the field--Exception: ");
    strMessage += e->m_pErrorInfo->m_strDescription; AfxMessageBox(strMessage); // indicate failure
    bSuccess = FALSE;
    }
    AND_CATCH (CMemoryException, e)
    {
    AfxMessageBox(_T("Failed to delete the field--Memory exception thrown.")); // indicate failure
    bSuccess = FALSE;
    }
    END_CATCH return bSuccess;
    }void deleteTable(CDaoDatabase *pDatabase, CString strTableName)
    {
    // if the database is non-existent, then the answer is obvious
    if (pDatabase == NULL)
    return; // see if there is a table by this name -- if not, can't proceed
    if (!IsExistentTable(pDatabase, strTableName))
    return; // MFC exception handler macros used
    TRY
    {
    pDatabase->DeleteTableDef(strTableName);
    }
    CATCH (CDaoException, e)
    {
    // construct a meaningful message if request
    CString strMessage = _T("Couldn't delete the table--Exception: ");
    strMessage += e->m_pErrorInfo->m_strDescription; AfxMessageBox(strMessage);
    }
    AND_CATCH (CMemoryException, e)
    {
    // output status if requested
    AfxMessageBox(_T("Failed to delete the table--Memory exception thrown."));
    }
    END_CATCH return;
    }BOOL IsExistentField(CDaoTableDef *pTableDef, CString strFieldName)
    {
    // if the tabledef is non-existent, then the answer is obvious
    if (pTableDef == NULL)
    return FALSE; // initialize status indicator
    BOOL bDuplicateFieldName = TRUE; // see if there is a field by this name already--duplicate
    // named fields are not accepted
    CDaoFieldInfo fieldInfo;    // only needed for the call // MFC exception handler macros used
    TRY
    {
    // this call will throw an exception if there is no
    // field by the specified name--test for duplication
    pTableDef->GetFieldInfo(strFieldName, fieldInfo);
    }
    CATCH (CDaoException, e)
    {
    // if this is an 'Item not found' exception, we are
    // cleared to create the field -- else this is
    // a duplicate field name and we got another exception
    // which is irrelevant for our purposes
    if (e->m_pErrorInfo->m_lErrorCode == 3265)
    bDuplicateFieldName = FALSE;
    }
    AND_CATCH (CMemoryException, e)
    {
    // do nothing--no need to process errors since this is
    // just a duplicate checker
    }
    END_CATCH return bDuplicateFieldName;
    }int GetMaxOutLevel(CDaoRecordset &rs, int valnum)
    {
    int n_Maxlevel = 0 ;
    while(!rs.IsEOF())
    {
    //get max level
    COleVariant var;
    int n_Templevel = 0 ;
    var = rs.GetFieldValue(valnum);
    CString strlevel = CCrack::strVARIANT(var);
    n_Templevel = atoi(strlevel);
    if(n_Templevel>n_Maxlevel)
    n_Maxlevel = n_Templevel;
    rs.MoveNext();
    }
    return n_Maxlevel;
    }void RepairDb(CString strDbPath) 
    {
    CWaitCursor theWait; try
    {
    CDaoWorkspace::RepairDatabase(strDbPath);
    }
    catch(CDaoException* pe)
    {
    pe->ReportError();
    pe->Delete();
    }
    }void CompactDb(CString strDbPath) 
    {
    CWaitCursor theWait;
    /* AfxDaoInit();
    _DAODBEngine* pEngine = AfxGetDaoState()->m_pDAODBEngine;
    TlsSetValue(dwDBEngineSlot, pEngine);
    AfxGetDaoState()->m_pDAODBEngine = (DAODBEngine *)TlsGetValue(dwDBEngineSlot);
    ASSERT(AfxGetDaoState()->m_pDAODBEngine!=NULL);
    */
    try
    {
    CString strTempPath;
    CString strTempFile; GetTempPath(MAX_PATH, strTempPath.GetBuffer(MAX_PATH));
    strTempPath.ReleaseBuffer(); GetTempFileName(strTempPath, _T("1234"), GetTickCount(), strTempFile.GetBuffer(MAX_PATH));
    strTempFile.ReleaseBuffer(); CDaoWorkspace::CompactDatabase(strDbPath, strTempFile); DeleteFile(strDbPath);
    MoveFile(strTempFile, strDbPath);
    }
    catch(CDaoException* pe)
    {
    pe->ReportError();
    pe->Delete();
    }
    catch(CMemoryException*)
    {
    AfxMessageBox("Out of memory");
    }
    }
    *****************************************以上大部分来自MSDN的例程*****************************************
      

  4.   

    使用ODBC API直接操作数据库,其实CDatabase,CRecordset也是微软封装的类,通过SQLAPI来操作数据库的。在开发文档当中有一些相关的文章,也许对你有帮助。
      

  5.   

    用ADO呀
    m_strConnection.Format("Provider=MSDASQL.1;Password=%s;Persist Security Info=True;User ID=%s;Data Source=%s",m_strPassWord,m_strUserName,m_strDataSource);
    CString m_strCmdText ;
    m_strCmdText.Format("select * from T_AttachFiles where id=%s",sID); _RecordsetPtr    pRs;
    pRs.CreateInstance(__uuidof(Recordset));
    //打开记录集
    pRs->Open((LPCTSTR)m_strCmdText, (LPCTSTR)m_strConnection, adOpenStatic, 
    adLockReadOnly, adCmdText);
    _variant_t vData;
    vData=pRs->GetCollect(_variant_t("Data"));
                。。
      

  6.   

    如果是SQL Server,可以用DBLibrary,MSDN上面有!
      

  7.   

    使用SDK编写程序,最好使用Pro*C来进行数据库操作,优点是:
    1.速度快
    2.代码简单
    3.完全不用MFC和C++特性
      

  8.   

    使用下述两个控件即可。Microsoft DataGrid Control, Version 6.0 (OLEDB)
    Microsoft ADO Data Control, version 6.0 (OLEDB)