ADO 데이터베이스 접근 기술

1. ADO (active data object, 활동 데이터 대상) 는 사실상 COM (구성 요소 대상 모델) 을 기반 으로 하 는 자동화 인터페이스 기술 로 OLE DB (대상 연결 과 끼 워 넣 은 데이터베이스) 를 바탕 으로 OLE DB 가 정성 들 여 포장 한 데이터베이스 접근 기술 을 이용 하여 데이터베이스 응용 프로그램 을 신속하게 만 들 수 있다.ADO 는 일반적인 데이터 접근 디 테 일 을 패키지 하 는 매우 간단 한 대상 을 제공 합 니 다.ODBC 데이터 원본 도 일반적인 OLE DB Privider 를 제공 하기 때문에 ADO 는 자체 OLE DB Privider 뿐만 아니 라 모든 ODBC 드라이버 를 적용 할 수 있다.
    모든 일 은 시작 이 어렵 고 어떤 신기 술 이 초보 자 에 게 가장 중요 한 것 은 '입문' 이 며 그 요점 을 파악 하 는 것 이다.ADO 데이터베이스 개발 의 기본 절 차 를 살 펴 보 자!그것 의 기본 절 차 는 다음 과 같다.
(1) COM 라 이브 러 리 초기 화, ADO 라 이브 러 리 정의 파일 도입
(2) Connection 대상 으로 데이터베이스 연결
(3) 만들어 진 연결 을 이용 하여 Connection, Command 대상 을 통 해 SQL 명령 을 수행 하거나 Recordset 대상 을 이용 하여 결과 기록 집 을 조회, 처리 합 니 다.
(4) 사용 완료 후 연결 해제 대상 을 닫 습 니 다.
2. ADO 의 세 핵심 대상
   Connection 대상: 데이터 베 이 스 를 연결 하고 응용 프로그램 과 데이터 베이스 간 의 통신 을 관리 합 니 다.Command 와 Recordset 대상 은 모두 ActiveConnection 속성 을 가지 고 있 으 며, 이 속성 은 Connection 대상 을 참조 합 니 다.
   command 대상: 반복 적 으로 실 행 된 조 회 를 처리 하거나 저장 과정 에서 호출 된 출력 이나 매개 변 수 를 되 돌려 주 는 값 을 검사 해 야 하 는 조 회 를 처리 합 니 다.
   Recordset 대상: 데 이 터 를 가 져 오 는 데 사 용 됩 니 다.Recordset 대상 이 조회 결 과 를 저장 합 니 다. 이 결 과 는 데이터 의 줄 (기록 이 됨) 과 열 (필드 라 고 함) 로 구성 되 어 있 습 니 다.모든 열 은 Recordset 의 Fields 집합 에 있 는 Fields 대상 에 저 장 됩 니 다.
      
3. 저 희 는 원 라 이브 러 리 구조, 데이터베이스 이름 Demo. mdb, 라 이브 러 리 이름 DemoTable, 표 내 필드 이름 Name (이름) 과 Age (연령) 의 두 필드 를 사용 하여 예제 프로그램 작업 에 필요 한 Access 데이터 베 이 스 를 구성 합 니 다.
        우선, ADO 를 지원 하 는 구성 요소 형식 라 이브 러 리 (*. tlb) 를 \ # import 구문 으로 참조 해 야 합 니 다. 그 중에서 형식 라 이브 러 리 는 실행 가능 한 프로그램 (DLL, EXE 등) 의 일부분 으로 자신의 프로그램 에 있 는 부속 자원 에 위치 할 수 있 습 니 다. 예 를 들 어 msado 15. dll 의 부속 자원 에 위치 하고 \ # import 로 직접 참조 하면 됩 니 다.Stdafx. h 파일 에 다음 문 구 를 직접 추가 할 수 있 습 니 다.
#import "c:\program files\common files\system\ado\msado15.dll" rename ("EOF", "adoEOF")  (한 줄 에 있 네)      
using namespace ADODB; 
이 중 경로 명 은 자신의 시스템 에 설 치 된 ADO 지원 파일 의 경로 에 따라 스스로 설정 할 수 있다.컴 파일 러 가 \ # import 문 구 를 만 났 을 때 구성 요소 형식 라 이브 러 리 의 인 터 페 이 스 를 참조 하기 위해 포장 류 를 생 성 합 니 다. \ # import 문 구 는 실제로 API 함수 LoadTypeLib () 를 실행 한 것 과 같 습 니 다. \ #import 문 구 는 프로젝트 실행 가능 한 프로그램 출력 디 렉 터 리 에 두 개의 파일 을 생 성 합 니 다. 각각 *. tlh (형식 라 이브 러 리 파일) 와 *. tli (형식 라 이브 러 리 구현 파일) 입 니 다. 각각 인터페이스 마다 스마트 포인 터 를 만 들 고 각종 인터페이스 방법, 매 거 유형, CLSID 등 진행 성명 을 통 해 일련의 포장 방법 을 만 듭 니 다.rename ("EOF", "adoEOF") 은 다른 라 이브 러 리 의 이름 과 충돌 하지 않도록 ADO 의 끝 표지 EOF 를 adoEOF 로 바 꾸 는 것 을 설명 합 니 다.    그 다음으로 프로그램 초기 과정 에서 구성 요 소 를 초기 화 해 야 합 니 다. 보통 CoInitialize (NULL) 를 사용 할 수 있 습 니 다.이 방법 은 끝 날 때 초기 화 된 COM 을 닫 으 려 면 다음 문 구 를 사용 하여 CoUnInitialize () 를 사용 할 수 있 습 니 다.닫 기 초기 화 를 위 한 COM.MFC 에 서 는 COM 을 초기 화 하 는 다른 방법 도 사용 할 수 있다. 이런 방법 은 한 문장 만 있 으 면 COM 을 초기 화하 고 끝 날 때 COM 을 닫 는 동작 을 자동 으로 실현 할 수 있다. 문 구 는 다음 과 같다. AfxOleInit ().    이어서 ADO 의 조작 을 직접 사용 할 수 있다.우리 가 자주 사용 하 는 것 은 앞에서 \ # import 문 구 를 사용 하여 유형 라 이브 러 리 를 참조 할 때 생 성 된 포장 류 입 니 다. tlh 에서 설명 한 스마트 포인터 중 세 개 입 니 다. 각각 입 니 다.ConnectionPtr、_RecordsetPtr 와CommandPtr。다음은 그들의 사용 방법 에 대해 소개 한다.
1、_ConnectionPtr 스마트 포인 터 는 라 이브 러 리 연결 을 열 고 닫 거나 Execute 방법 으로 SQL 명령 어 를 실행 하 는 데 사 용 됩 니 다. (용법 은 CommandPtr 의 Execute 방법 과 유사 합 니 다.)라 이브 러 리 연결 을 엽 니 다.먼저 인 스 턴 스 포인 터 를 만 들 고 Open 으로 라 이브 러 리 연결 을 열 면 IUnknown 의 자동화 인터페이스 포인 터 를 되 돌려 줍 니 다.코드 는 다음 과 같다.
_ConnectionPtr	m_pConnection;
//    COM,  ADO     
AfxOleInit();
m_pConnection.CreateInstance(__uuidof(Connection));

//  ADO           try...catch()       ,
//                    。jingzhou xu
try                 
{	
	//     Access Demo.mdb
	m_pConnection->Open("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=Demo.mdb","","",adModeUnknown);
        //  JET      ACCESS2000      :
}
catch(_com_error e)
{
	AfxMessageBox("       ,     Demo.mdb        !");
	return FALSE;
}      

Connection Open , :

HRESULT Connection15::Open ( _bstr_t ConnectionString, _bstr_t UserID, _bstr_t Password, long Options );

ConnectionString ; UserID ; Password ; Options , Connection , Options :

adModeUnknown: 。

adModeRead:

adModeWrite:

adModeReadWrite:

adModeShareDenyRead: Connection

adModeShareDenyWrite: Connection

adModeShareExclusive: Connection

adModeShareDenyNone: Connection

Connection Open() , Connection ConnectionTimeOut State。ConnectionTimeOut , Open , :

m_pConnection->ConnectionTimeout = 5;/// 5 m_pConnection->Open("Data Source=adotest;","","",adModeUnknown);

State Connection ,0 ,1 , ,

 


- 라 이브 러 리 연결 을 닫 습 니 다.연결 상태 가 유효 하 다 면 닫 기 방법 으로 닫 고 빈 값 을 부여 합 니 다.코드 는 다음 과 같다.
if(m_pConnection->State)
        m_pConnection->Close();
m_pConnection= NULL;      

 


2、_RecordsetPtr 스마트 포인터 로 라 이브 러 리 데이터 시트 를 열 수 있 고 표 안의 기록, 필드 등 을 여러 가지 조작 할 수 있 습 니 다.데이터 시트 를 열다.라 이브 러 리 내 표 이름 이 DemoTable 인 데이터 시트 를 엽 니 다. 코드 는 다음 과 같 습 니 다.
_RecordsetPtr	m_pRecordset;
m_pRecordset.CreateInstance(__uuidof(Recordset));

//  ADO           try...catch()       ,
//                    。jingzhou xu
try
{
	m_pRecordset->Open("SELECT * FROM DemoTable",                //   DemoTable      
						theApp.m_pConnection.GetInterfacePtr(),	 //       IDispatch  
						adOpenDynamic,
						adLockOptimistic,
						adCmdText);
}
catch(_com_error *e)
{
	AfxMessageBox(e->ErrorMessage());
}      

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 Connection Execute() 。


- 표 내 데 이 터 를 읽 습 니 다.표 안의 데 이 터 를 모두 읽 고 목록 상자 에 표시 합 니 다. mAccessList 는 목록 상자 의 구성원 변수 이름 입 니 다.표 끝 표지 adoEOF 가 없 으 면 GetCollect (필드 이름) 또는 mpRecordset - > Fields - > GetItem (필드 이름) - > Value 방법 으로 현재 기록 포인터 가 가리 키 는 필드 값 을 가 져 온 다음 MoveNext () 방법 으로 다음 기록 위치 로 이동 합 니 다.코드 는 다음 과 같다.
_variant_t var;
CString strName,strAge;
	try
	{
		if(!m_pRecordset->BOF)
			m_pRecordset->MoveFirst();
		else
		{
			AfxMessageBox("      ");
			return;
		}

		//               
		while(!m_pRecordset->adoEOF)
		{
			var = m_pRecordset->GetCollect("Name");
			if(var.vt != VT_NULL)
				strName = (LPCSTR)_bstr_t(var);
			var = m_pRecordset->GetCollect("Age");
			if(var.vt != VT_NULL)
				strAge = (LPCSTR)_bstr_t(var);

			m_AccessList.AddString( strName + " --> "+strAge );

			m_pRecordset->MoveNext();
		}

		//          ,           
		m_AccessList.SetCurSel(0);
	}
	catch(_com_error *e)
	{
		AfxMessageBox(e->ErrorMessage());
	}     

- 기록 삽입.먼저 AddNew () 방법 으로 빈 기록 을 추가 한 다음 PutCollect (필드 이름, 값) 로 각 필드 의 값 을 입력 하고 마지막 으로 Update () 를 라 이브 러 리 에 업데이트 하면 됩 니 다.그 중 변수 mName 과 mAge 는 각각 이름과 나이 편집 상자 의 구성원 변수 이름 입 니 다.코드 아래:
try
	{
		//       
		m_pRecordset->AddNew();
		m_pRecordset->PutCollect("Name", _variant_t(m_Name));
		m_pRecordset->PutCollect("Age", atol(m_Age));
		m_pRecordset->Update();

		AfxMessageBox("    !");
	}
	catch(_com_error *e)
	{
		AfxMessageBox(e->ErrorMessage());
	}      

- 이동 기록 포인터.이동 기록 포인 터 는 MoveFirst () 방법 으로 첫 번 째 기록, MoveLast () 방법 으로 마지막 기록, MovePrevious () 방법 으로 현재 기록 의 이전 기록, MoveNext () 방법 으로 현재 기록 의 다음 기록 으로 이동 할 수 있다.그러나 우 리 는 기록 지침 을 임의로 기록 위치 로 이동 해 야 할 때 Move (기록 번호) 방법 으로 이 루어 질 수 있 습 니 다. 주의: Move () 방법 은 현재 기록 에 비해 포인터 위 치 를 이동 하 는 것 입 니 다. 플러스 는 뒤로 이동 하고 마이너스 는 앞으로 이동 합 니 다. 예 를 들 어 Move (3), 현재 기록 은 3 일 때 기록 3 부터 3 개의 기록 위 치 를 뒤로 이동 합 니 다.코드 는 다음 과 같다.
	try
	{
		int curSel = m_AccessList.GetCurSel();	
		//            ,                     
		m_pRecordset->MoveFirst();
		m_pRecordset->Move(long(curSel));
		
	}
	catch(_com_error *e)
	{
		AfxMessageBox(e->ErrorMessage());
	}      

- 기록 의 필드 값 을 수정 합 니 다.기록 포인 터 를 기록 을 수정 할 위치 로 이동 하여 PutCollect (필드 이름, 값) 로 새 값 을 기록 하고 업데이트 () 로 데이터 베 이 스 를 업데이트 할 수 있 습 니 다.위의 방법 으로 기록 지침 을 이동 할 수 있 습 니 다. 필드 값 코드 를 수정 하면 다음 과 같 습 니 다.
	try
	{
		//             
		m_pRecordset->MoveFirst();
		m_pRecordset->Move(1);        //  0  
		m_pRecordset->PutCollect("Name", _variant_t(m_Name));
		m_pRecordset->PutCollect("Age", atol(m_Age));
		m_pRecordset->Update();
	}
	catch(_com_error *e)
	{
		AfxMessageBox(e->ErrorMessage());
	}      

- 기록 삭제.기록 을 삭제 하 는 것 은 위 에서 기록 을 수정 하 는 작업 과 유사 합 니 다. 기록 지침 을 기록 을 수정 할 위치 로 이동 하고 Delete () 방법 으로 삭제 하 며 Update () 로 데이터 베 이 스 를 업데이트 하 는 것 도 가능 합 니 다.코드 는 다음 과 같다.
	try
	{
		//          
		m_pRecordset->MoveFirst();
		m_pRecordset->Move(1);        //  0  
		m_pRecordset->Delete(adAffectCurrent);  //   adAffectCurrent       
		m_pRecordset->Update();
	}
	catch(_com_error *e)
	{
		AfxMessageBox(e->ErrorMessage());
	}      

- 기록 집 을 닫 습 니 다.기록 집합 을 닫 고 빈 값 을 부여 합 니 다.코드 는 다음 과 같다.
	m_pRecordset->Close();
	m_pRecordset = NULL;      

3 、 CommandPtr 스마트 포인터, 사용 가능ConnectionPtr 또는RecordsetPtr 는 작업 을 수행 하고 출력 파 라 메 터 를 정의 하 며 저장 과정 이나 SQL 문 구 를 수행 합 니 다.
(보충: ADO Command 대상 은 데이터 베 이 스 를 위 한 간단 한 조 회 를 수행 하 는 데 사 용 됩 니 다. 이 조 회 는 기록 을 만 들 거나 추가 하거나 되 찾 거나 삭제 하거나 업데이트 하 는 등 동작 을 수행 할 수 있 습 니 다.
이 조회 가 데 이 터 를 되 찾 는 데 사용 된다 면 이 데 이 터 는 RecordSet 대상 으로 되 돌아 갑 니 다. 이 는 되 찾 은 데 이 터 는 RecordSet 대상 의 속성, 집합, 방법 또는 이벤트 에 의 해 작 동 될 수 있 음 을 의미 합 니 다.
command 대상 의 주요 특성 은 저장 조회 와 파 라 메 터 를 가 진 저장 과정 을 사용 할 수 있 는 능력 이 있 습 니 다.)
- SQL 문 구 를 실행 합 니 다.먼저 하나 만 들 기CommandPtr 인 스 턴 스 포인터, 라 이브 러 리 연결 과 SQL 문 구 를 매개 변수 로 하여 Execute () 방법 을 실행 할 수 있 습 니 다.코드 는 다음 과 같다.
_CommandPtr		m_pCommand;
m_pCommand.CreateInstance(__uuidof(Command));
m_pCommand->ActiveConnection = m_pConnection;  //        
m_pCommand->CommandText = "SELECT * FROM DemoTable";  // SQL  
m_pRecordset = m_pCommand->Execute(NULL, NULL,adCmdText); //   SQL  ,           

- 저장 프로 세 스 를 실행 합 니 다.저장 프로 세 스 를 실행 하 는 작업 은 위 에서 실행 하 는 SQL 문장 과 유사 합 니 다. 다른 점 은 CommandText 매개 변수 에서 SQL 문장 이 아니 라 저장 프로 세 스 의 이름 입 니 다. 예 를 들 어 Demo.또 다른 차이 점 은 Execute () 에서 매개 변 수 는 adcmdText (SQL 문 구 를 실행) 에서 adcmdStored Proc 로 저장 과정 을 수행 하 는 것 이다.저장 과정 에서 입 출력 매개 변수 가 존재 한다 면 다른 스마트 포인터 에 사용 해 야 합 니 다ParameterPtr 는 입력, 출력 할 매개 변수 정 보 를 차례대로 설정 하고 이 를 에 부여 합 니 다.CommandPtr 에서 Parameters 매개 변 수 는 정 보 를 전달 하고 관심 이 있 는 독 자 는 관련 서적 이나 MSDN 을 스스로 찾 을 수 있 습 니 다.저장 프로 세 스 를 실행 하 는 코드 는 다음 과 같 습 니 다.
_CommandPtr		m_pCommand;
m_pCommand.CreateInstance(__uuidof(Command));
  m_pCommand->ActiveConnection = m_pConnection;  //        
m_pCommand->CommandText = "Demo";  
  m_pCommand->Execute(NULL,NULL, adCmdStoredProc);      

4. 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  CommandText    。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 m_pRecordset->Close();/// CString message; message.Format(" %d ",vCount.lVal); AfxMessageBox(message);///


 2. Command 대상 을 이용 하여 SQL 명령 을 수행 합 니 다.
위 에서 이미 서술 한 적 이 있다
3. Recordset 대상 을 직접 조회 하여 기록 집 을 얻는다.
위 에서 도 서술 하 였 다

좋은 웹페이지 즐겨찾기