繞過 MFC `CDatabase`/`CRecordset`,直接呼叫 ODBC 核心 API (`SQLAllocEnv`、`SQLAllocConnect`、`SQLConnect`、`SQLExecDirect`、`SQLBindCol`、`SQLFetch`),可獲得最大控制權與效能。本文提供完整句柄管理流程、參數綁定讀取範例、Access 專用建立/壓縮/取得資料庫名稱/DSN 管理函數封裝。
// 1. 配置環境
SQLHENV henv; SQLAllocEnv(&henv);
// 2. 配置連線
SQLHDBC hdbc; SQLAllocConnect(henv, &hdbc);
// 3. 連線資料源 (DSN 需預建)
SQLConnect(hdbc, (UCHAR*)"MyDSN", SQL_NTS, NULL, 0, NULL, 0);
// 4. 配置陳述句柄
SQLHSTMT hstmt; SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt);
// 5. 執行 SQL (直接執行)
CString sql = _T("SELECT NID, ARIQI, NJINE FROM HHZhiChu WHERE NID=123");
SQLExecDirect(hstmt, (UCHAR*)(LPCTSTR)sql, SQL_NTS);
// 6. 綁定結果欄位到變數
SQLINTEGER cb;
SQLBindCol(hstmt, 1, SQL_C_SLONG, &nid, 0, &cb);
SQLBindCol(hstmt, 2, SQL_C_TIMESTAMP, &ts, 0, &cb);
SQLBindCol(hstmt, 3, SQL_C_DOUBLE, &amt, 0, &cb);
// 7. 擷取資料
if (SQLFetch(hstmt) == SQL_SUCCESS) {
// 使用 nid, ts, amt...
}
// 8. 清理 (逆序)
SQLFreeHandle(SQL_HANDLE_STMT, hstmt);
SQLDisconnect(hdbc);
SQLFreeHandle(SQL_HANDLE_DBC, hdbc);
SQLFreeHandle(SQL_HANDLE_ENV, henv);
| 操作 | API / 代碼片段 |
|---|---|
| 建立 .mdb | `SQLConfigDataSource(NULL, ODBC_ADD_DSN, "Microsoft Access Driver (*.mdb)", "CREATE_DB=c:\\db.mdb General")` |
| 壓縮修復 | `SQLConfigDataSource(NULL, ODBC_ADD_DSN, driver, "COMPACT_DB=src.mdb dest.mdb General")` |
| 取得資料庫名稱 | `SQLGetInfo(hdbc, SQL_DATABASE_NAME, buf, sizeof(buf), &len)` |
| 建立 DSN | `SQLConfigDataSource(NULL, ODBC_ADD_DSN, driver, "DSN=MyDSN\0DBQ=c:\\db.mdb\0")` |
| 刪除 DSN | `SQLConfigDataSource(NULL, ODBC_REMOVE_DSN, driver, "DSN=MyDSN")` |
| 枚舉系統 DSN | `SQLDataSources(henv, SQL_FETCH_FIRST/NEXT, dsnBuf, ..., drvBuf, ...)` |
| 列舉資料表 | `SQLTables(hstmt, NULL,0, NULL,0, NULL,0, NULL,0)` → `SQLBindCol(hstmt, 3, SQL_C_CHAR, tableName, ...)` |
RETCODE rc = SQLExecDirect(hstmt, ...);
if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) {
SQLCHAR sqlState[6], msg[SQL_MAX_MESSAGE_LENGTH];
SQLINTEGER nativeErr;
SQLSMALLINT msgLen;
SQLError(henv, hdbc, hstmt, sqlState, &nativeErr, msg, sizeof(msg), &msgLen);
// 處理錯誤...
}