VC 데이터베이스 프로그래밍 ADO 예

12497 단어
1. 응용 프로그램 프레임워크를 생성하고 OLE/COM 라이브러리 환경을 초기화하여 표준 MFC AppWizard(exe) 응용 프로그램을 만들고 ADO 데이터베이스를 사용하는 InitInstance 함수에서 OLE/COM 라이브러리를 초기화한다(ADO 라이브러리는 COM DLL 라이브러리이기 때문이다).이 예는 다음과 같습니다.
 BOOL CAdotestDlg::OnInitDialog()
 {
        ::CoInitialize(NULL); //   OLE/COM    
  } 

프로그램 마지막 호출::CoUninitialize(),//프로그램이 차지하는 COM 자원을 방출합니다.또한:
m_pRecordset->Close();   !!!      !!!!!!!!!!!!
m_pConnection->Close();
m_pRecordset = NULL;
m_pConnection = NULL; 

  2. ADO 라이브러리 파일을 가져오려면 ADO를 사용하기 전에 프로젝트의 stdafx를 사용해야 합니다.l 파일은 마지막으로 컴파일러가 정확하게 컴파일할 수 있도록 기호 # import을 직접 도입하여 ADO 라이브러리 파일을 도입합니다.코드는 다음과 같습니다. #import "C:\Program Files\common files\system\ado\msado15.dll"noADO 클래스는 ADO DLL (msado 15.dll) 에 자원으로 저장되는 것으로 그 내부에서 형식 라이브러리라고 부른다.유형 라이브러리는 자치 인터페이스와 C++에서 사용하는 COM vtable 인터페이스를 설명합니다.# import 명령을 사용할 때, 실행할 때 Visual C++++ 는 ADO DLL에서 이 형식 라이브러리를 읽고, 이를 통해 C++ + 헤더 파일을 만들어야 합니다.이 헤더 파일들은 가지고 있다.tli와.tlh 확장자, 독자는 프로젝트의 디렉터리에서 이 두 파일을 찾을 수 있습니다.이러한 파일에서 C++ 프로그램 코드에서 호출되는 ADO 클래스를 정의합니다.프로그램의 세 번째 줄은 ADO 객체가 이름 공간을 사용하지 않음을 나타냅니다.일부 응용 프로그램에서는 응용 프로그램의 대상과 ADO의 대상 사이에 명칭 충돌이 발생할 수 있기 때문에 명칭 공간을 사용할 필요가 있습니다.이름 공간을 사용하려면 세 번째 줄 프로그램을 다음과 같이 수정할 수 있습니다:renamenamespace("AdoNS").네 번째 줄 코드는 ADO의 EOF (파일 끝) 를 adoEOF로 변경하여 자신의 EOF를 정의한 다른 라이브러리와 충돌하지 않도록 합니다.3. 스마트 포인터를 이용하여 데이터베이스 조작을 하고CaboutDlg 헤더 파일에 두 개의 ADO 스마트 포인터 클래스 실례를 정의하고 대화상자에ListCtrl을 추가한다.
 class CAdotestDlg : public CDialog
{
     _ConnectionPtr m_pConnection;
     _RecordsetPtr m_pRecordset;
   ClistCtrl m_List; 
     ......
}     

ADO 라이브러리에는 세 가지 지능형 포인터가 있습니다.ConnectionPtr、_CommandPtr 및RecordsetPtr.   _ConnectionPtr는 일반적으로 데이터 연결을 만들거나 결과를 반환하지 않는 SQL 문을 실행하는 데 사용됩니다. 예를 들어 저장 프로세스입니다.  _CommandPtr에서 레코드세트를 반환합니다.레코드세트를 반환하는 저장 프로세스와 SQL 문을 실행하는 간단한 방법을 제공합니다.사용 중CommandPtr 커넥터 사용 시 전역ConnectionPtr 커넥터 또는CommandPtr 인터페이스에서 직접 연결 문자열을 사용합니다.  _RecordsetPtr는 레코드세트 객체입니다.상기 두 가지 대상에 비해 기록 집합에 더 많은 제어 기능을 제공했다. 예를 들어 기록 잠금, 커서 제어 등이다.OnButton1은 ADO 프로그램을 사용한 이벤트 응답에 다음 코드를 포함합니다.
void CAdotestDlg::OnButton1() { m_List.ResetContent(); m_pConnection.CreateInstance(_uuidof(Connection)); //   Connection   m_pRecordset.CreateInstance(_uuidof(Recordset));//   Recordset   try { m_pConnection->Open("DSN=ADOTest","","",0); //    ADOTest ODBC    //  :         ID    open    //       ->Open("DSN=test;uid=sa;pwd=123;","","",0); //   SQL                m_pRecordset CString strSql="select * from middle"; BSTR bstrSQL = strSql.AllocSysString(); m_pRecordset->Open(bstrSQL,(IDispatch*)m_pConnection,adOpenDynamic,adLockOptimistic, adCmdText); //adOpenDynamic:   adLockOptimistic      adCmdText:       while(!m_pRecordset->adoEOF)//       { //           _variant_t TheValue; //VARIANT     TheValue = m_pRecordset->GetCollect("BIG_NAME");//    BIG_NAME   if(TheValue.vt!=VT_NULL) m_List.AddString((char*)_bstr_t(TheValue)); //            //           // _bstr_t TheValue1=m_pRecordset->Fields->GetItem("BIG_NAME")->Value; // CString temp=TheValue1.copy(); // m_List.AddString(temp); //       _variant_t vUsername,vBirthday,vID,vOld; TRACE("id:%d,  :%s,  :%d,  :%s\r
", vID.lVal,(LPCTSTR)(_bstr_t)vUsername,vOld.lVal,(LPCTSTR)(_bstr_t)vBirthday); m_pRecordset->MoveNext();// } m_pRecordset->Close(); m_pConnection->Close(); } catch (_com_error e)// { AfxMessageBox(e.ErrorMessage()); } m_pRecordset->Close(); // !!! !!!! m_pConnection->Close(); m_pRecordset = NULL; m_pConnection = NULL; }

프로그램 통과variant_t와bstr_t 변환 COM 객체 및 C++ 유형의 데이터,variant_T클래스는 OLE 자치 VARIANT 데이터 유형을 캡슐화합니다.C++에서 사용variant_T클래스는 VARIANT 데이터 유형을 직접 사용하는 것보다 훨씬 쉽습니다.좋아, 컴파일하면 이 프로그램은 실행될 수 있지만, 실행하기 전에 ADOtest라는 ODBC 데이터 원본을 만들어야 한다는 것을 기억해라.이 프로그램은 테이블 middle의 BIG 를NAME 필드 값이 목록 컨트롤에 표시됩니다.
4. SQL 명령을 실행하고 결과 기록 집합을 가져옵니다. 결과 기록 집합을 얻기 위해 Recordset 대상을 가리키는 바늘을 정의합니다:RecordsetPtr m_pRecordset; Recordset 객체의 인스턴스를 작성합니다. mpRecordset.CreateInstance("ADODB.Recordset"); SQL 명령의 실행은 여러 가지 형식을 채택할 수 있는데, 다음은 우리가 논술하고자 한다.(1) Connection 객체의 Execute 방법을 사용하여 SQL 명령 Execute 방법을 실행하는 방법의 원형은 다음과 같습니다.
     _RecordsetPtr Connection15::Execute ( _bstr_t CommandText, VARIANT * RecordsAffected,
 long Options ) 
       CommandText     ,   SQL  。
   RecordsAffected            , 
   Options  CommandText      ,Options        :
 adCmdText:  CommandText     
 adCmdTable:  CommandText     
 adCmdProc:  CommandText       
 adCmdUnknown:  
    Execute                ,              。 
    _variant_t RecordsAffected;
    ///  SQL  :CREATE TABLE    users,users      :  ID,   username,
  old,   birthday
    m_pConnection->Execute("CREATE TABLE users(ID INTEGER,username TEXT,old INTEGER,birthday 
DATETIME)",
   &RecordsAffected,
   adCmdText);
    ///         
    m_pConnection->Execute("INSERT INTO users(ID,username,old,birthday) VALUES 
(1, ''''Washington'''',25,''''1970/1/1'''')",&RecordsAffected,adCmdText);
    ///     old      
    m_pConnection->Execute("UPDATE users SET old = old+1",&RecordsAffected,adCmdText);
    ///  SQL                
    m_pRecordset =  m_pConnection->Execute("SELECT COUNT(*) FROM users",&RecordsAffected,adCmdText);
    _variant_t vIndex = (long)0;
    _variant_t vCount = m_pRecordset->GetCollect(vIndex);///           vCount  
           — _variant_t vCount = m_pRecordset->GetCollect((_variant_t)((long)0));
    m_pRecordset->Close();///     
    CString message;
    message.Format("  %d   ",vCount.lVal);
    AfxMessageBox(message);///        

(2) Command 객체를 이용한 SQL 명령 실행
_CommandPtr m_pCommand;
m_pCommand.CreateInstance("ADODB.Command");
_variant_t vNULL;
vNULL.vt = VT_ERROR;
vNULL.scode = DISP_E_PARAMNOTFOUND;///      
m_pCommand->ActiveConnection = m_pConnection;///       ,          
m_pCommand->CommandText = "SELECT * FROM users";///    
m_pRecordset = m_pCommand->Execute(&vNULL,&vNULL,adCmdText);///    ,     

이 코드에서 우리는 Command 대상으로만 SELECT 조회 문구를 집행했을 뿐 Command 대상은 저장 프로세스를 호출하는 과정에서 그 역할을 진정으로 나타낼 수 있다.다음에 우리는 상세하게 소개할 것이다.(3) Recordset 객체로 직접 조회하여 레코드세트 인스턴스 가져오기
void CGmsaDlg::OnDBSelect() 
{
    // TODO: Add your control notification handler code here
     _RecordsetPtr Rs1;  //  Recordset  
    _bstr_t Connect("DSN=GMS;UID=sa;PWD=;");//       
    _bstr_t Source ("SELECT count(*) FROM buaa.mdb010");  //    SQL  
    ::CoInitialize(NULL);    //   Rs1  
        HRESUL hr = Rs1.CreateInstance( __uuidof( Recordset ) );
       //      hr    
     Rs1->Open( Source,
            Connect,
                adOpenForwardOnly,
                    adLockReadOnly,
            -1 ); 
    _variant_t temp=Rs1->GetCollect(_variant_t((long)0));
    CString strTemp=(char* )(_bstr_t)temp;
    MessageBox("OK!"+strTemp);
}
   
  m_pRecordset->Open("SELECT * FROM users",
  _variant_t((IDispatch *)m_pConnection,true),
  adOpenStatic,
  adLockOptimistic,
  adCmdText);
Open         :
HRESULT Recordset15::Open ( const _variant_t & Source, 
   const _variant_t & ActiveConnection, 
   enum CursorTypeEnum CursorType, 
   enum LockTypeEnum LockType, 
   long Options ) 
  :
①Source        
②ActiveConnection         (     Connection         _variant_t  ) 
③CursorType    ,         ,        :
enum CursorTypeEnum
{
 adOpenUnspecified = -1,///      
 adOpenForwardOnly = 0,///      。             ,   MoveNext    ,   
         。   BookMark,RecordCount,AbsolutePosition,AbsolutePage     
 adOpenKeyset = 1,///                    、    ,           
       。
 adOpenDynamic = 2,///    。                        。
 adOpenStatic = 3///    。               ,        、  、      
           。
};
④LockType    ,         ,        :
enum LockTypeEnum
{
 adLockUnspecified = -1,///   
 adLockReadOnly = 1,///     
 adLockPessimistic = 2,      。              ,          
 adLockOptimistic = 3,      。      Update        。         
     、  、     
 adLockBatchOptimistic = 4,      。         ,  、           
    。
}; 
⑤Options        :
 adCmdText:  CommandText     
 adCmdTable:  CommandText     
 adCmdProc:  CommandText       
 adCmdUnknown:  
5.       、  

                SQL      users ,       :ID,username,old,birthday
       :     ,      ,       ,      ,          ,
     ,      。 
_variant_t vUsername,vBirthday,vID,vOld;
_RecordsetPtr m_pRecordset;
m_pRecordset.CreateInstance("ADODB.Recordset");
m_pRecordset->Open("SELECT * FROM users",
  _variant_t((IDispatch*)m_pConnection,true),
  adOpenStatic,
  adLockOptimistic,
  adCmdText);
while(!m_pRecordset->adoEOF)
{
    vID = m_pRecordset->GetCollect(_variant_t((long)0));///   1   , 0    ,
    ///            ,    
    vUsername = m_pRecordset->GetCollect("username");///  username    
    vOld = m_pRecordset->GetCollect("old");
    vBirthday = m_pRecordset->GetCollect("birthday");
    /// DEBUG    OUTPUT           
    if(vID.vt != VT_NULL && vUsername.vt != VT_NULL && vOld.vt != VT_NULL && vBirthday.vt
 != VT_NULL)
        TRACE("id:%d,  :%s,  :%d,  :%s\r
", vID.lVal, (LPCTSTR)(_bstr_t)vUsername, vOld.lVal, (LPCTSTR)(_bstr_t)vBirthday); m_pRecordset->MoveNext();/// } m_pRecordset->MoveFirst();/// m_pRecordset->Delete(adAffectCurrent);/// /// for(int i=0;i<3;i++) { m_pRecordset->AddNew();/// m_pRecordset->PutCollect("ID",_variant_t((long)(i+10))); m_pRecordset->PutCollect("username",_variant_t(" ")); m_pRecordset->PutCollect("old",_variant_t((long)71)); m_pRecordset->PutCollect("birthday",_variant_t("1930-3-15")); } m_pRecordset->Move(1,_variant_t((long)adBookmarkFirst));/// , m_pRecordset->PutCollect(_variant_t("old"),_variant_t((long)45));/// m_pRecordset->Update();///
비고: 여러 번 조회하면 조회 과정을 하나의 함수로 만들 수 있다ExecuteSQL은 mpRecordset 획득 연결 포인터 mpConnection 쿼리 결과
void ExecuteSQL(_ConnectionPtr  m_pConnection, _RecordsetPtr  m_pRecordset,CString strSql)
{
    //  Select   
    BSTR bstrSQL = strSql.AllocSysString();           
     try
     {
        m_pRecordset->Open(bstrSQL,(IDispatch*)m_pConnection,adOpenDynamic,adLockOptimistic,
adCmdText); 
            //adOpenDynamic:    adLockOptimistic       adCmdText:      
     }
     catch(_com_error error)
     {
        CString errorMessage;
        errorMessage.Format("%s",(LPTSTR)error.Description());
        AfxMessageBox(errorMessage);
     }
}        
//    :
3127——       
3092——       
  :
catch(const _com_error e)
{
     AfxMessageBox(e.Description());
     long errorCode=e.WCode();
     if(3127==errorCode) AfxMessageBox("    ");
     if(3092==errorCode) AfxMessageBox("     ");
     return FALSE;
}
새로운 블로그 체험


좋은 웹페이지 즐겨찾기