首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> VC >> VC++

VC++ ADO 開發實戰(一):基礎操作流程詳解

     編輯:VC++

前言

ADO 建構於 OLE DB 之上,比 ODBC API、DAO、RDO 更簡單易用且不失彈性。本文詳細說明 VC++ 下 ADO 開發基本流程與程式碼範例,採用 Access 資料庫供測試。

基本開發流程

  1. 初始化 COM 程式庫,匯入 ADO 類型庫
  2. 用 Connection 物件連接資料庫
  3. 利用 Connection、Command 執行 SQL,或用 Recordset 取得記錄集查詢處理
  4. 關閉連線、釋放物件

詳細步驟與程式碼

1. COM 初始化

BOOL CADOTestApp::InitInstance()
{
    AfxOleInit(); // 初始化 COM
    // ...
}

2. 匯入 ADO 類型庫

// stdafx.h
#import "C:\\Program Files\\Common Files\\System\\ADO\\msado15.dll" \
    no_namespace rename("EOF", "adoEOF")

編譯時可能出現 warning C4146,微軟建議忽略。

3. 建立 Connection 並連接資料庫

_ConnectionPtr m_pConnection;

BOOL CADOTestDlg::OnInitDialog()
{
    CDialog::OnInitDialog();
    HRESULT hr;
    try
    {
        hr = m_pConnection.CreateInstance(__uuidof(Connection));
        if (SUCCEEDED(hr))
        {
            // Access 2000
            hr = m_pConnection->Open(
                _T("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=test.mdb"),
                _T(""), _T(""), adModeUnknown);
            // Access 97 需改用 Provider=Microsoft.Jet.OLEDB.3.51
        }
    }
    catch (_com_error e)
    {
        CString msg;
        msg.Format(_T("連接失敗!\r\n%s"), e.ErrorMessage());
        AfxMessageBox(msg);
    }
    return TRUE;
}

常用連接字串

  • Jet 引擎:Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\\test.mdb
  • DSN:Data Source=adotest;UID=sa;PWD=;
  • SQL Server(無 DSN):driver={SQL Server};Server=127.0.0.1;DATABASE=db;UID=sa;PWD=123

Connection 實用屬性

  • ConnectionTimeout:設定逾時秒數,須在 Open 前呼叫
  • State:0=關閉、1=開啟,可用於判斷是否需關閉

4. 執行 SQL 並取得記錄集

定義 _RecordsetPtr m_pRecordset; 並 CreateInstance。

方式一:Connection::Execute

_variant_t vtAffected;
m_pConnection->Execute(_T("CREATE TABLE users(ID INT, username TEXT, old INT, birthday DATETIME)"), 
    &vtAffected, adCmdText);
m_pConnection->Execute(_T("INSERT INTO users VALUES(1, 'Washington', 25, '1970/1/1')"), 
    &vtAffected, adCmdText);
m_pConnection->Execute(_T("UPDATE users SET old = old+1"), &vtAffected, adCmdText);

m_pRecordset = m_pConnection->Execute(_T("SELECT COUNT(*) FROM users"), &vtAffected, adCmdText);
_variant_t vtCount = m_pRecordset->GetCollect((long)0);
m_pRecordset->Close();
AfxMessageBox(_T("記錄數: ") + CString((char*)_bstr_t(vtCount)));

方式二:Command 物件

_CommandPtr pCmd;
pCmd.CreateInstance(__uuidof(Command));
_variant_t vNull; vNull.vt = VT_ERROR; vNull.scode = DISP_E_PARAMNOTFOUND;

pCmd->ActiveConnection = m_pConnection;
pCmd->CommandText = _T("SELECT * FROM users");
m_pRecordset = pCmd->Execute(&vNull, &vNull, adCmdText);

方式三:Recordset::Open 直接查詢

m_pRecordset->Open(
    _T("SELECT * FROM users"),
    _variant_t((IDispatch*)m_pConnection, true),
    adOpenStatic, adLockOptimistic, adCmdText);

游標類型:adOpenForwardOnly(唯向前)、adOpenKeyset、adOpenDynamic(動態)、adOpenStatic(靜態快照)。
鎖定類型:adLockReadOnly、adLockPessimistic(悲觀)、adLockOptimistic(樂觀)、adLockBatchOptimistic(批次樂觀)。

5. 記錄集遍歷與更新

m_pRecordset->Open(_T("SELECT * FROM users"), ...);
while (!m_pRecordset->adoEOF)
{
    _variant_t vId = m_pRecordset->GetCollect(_T("ID"));
    _variant_t vName = m_pRecordset->GetCollect(_T("username"));
    // ... 處理資料
    m_pRecordset->MoveNext();
}

// 新增記錄
for (int i = 0; i < 3; i++)
{
    m_pRecordset->AddNew();
    m_pRecordset->PutCollect(_T("ID"), _variant_t(i + 10));
    m_pRecordset->PutCollect(_T("username"), _variant_t(_T("葉利欽")));
    m_pRecordset->PutCollect(_T("old"), _variant_t(71));
    m_pRecordset->PutCollect(_T("birthday"), _variant_t(_T("1930-3-15")));
}

// 移至第 2 筆並修改
m_pRecordset->Move(1, _variant_t(adBookmarkFirst));
m_pRecordset->PutCollect(_T("old"), _variant_t(45));
m_pRecordset->Update();

m_pRecordset->Close();
m_pConnection->Close();

後記

下一篇將介紹 Recordset 進階屬性/方法、綁定方式、預存程序、交易處理、圖片儲存、表格控件配合等主題。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved