首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

C++ 連接 SQL Server/MySQL/Oracle:ODBC、OLE DB、原生庫三大方案對比與代碼範例

     編輯:程式設計綜合問答

三大主流方案架構對比

方案適用資料庫優點缺點推薦場景
ODBC通用 (SQL Server, MySQL, Oracle, PG...)標準化、跨平台、驅動豐富效能稍低、API 繁瑣跨資料庫專案、Linux/Unix
OLE DBWindows 專用 (SQL Server, Oracle, Access...)COM 模型、功能豐富、Windows 效能佳僅限 Windows、微軟已停止更新舊式 Windows 桌面應用
原生庫特定資料庫效能最高、功能全、原生體驗綁定廠商、需分發客戶端高效能、深度整合專案

方案一:ODBC (推薦通用)

環境準備

  • 安裝對應 ODBC 驅動 (MySQL: MySQL Connector/ODBC; SQL Server: Microsoft ODBC Driver)
  • 配置系統 DSN (控制面板 → 管理工具 → ODBC 資料來源)

核心代碼 (Windows)

#include 
#include 
#include 
#include 

void checkError(SQLRETURN ret, SQLHANDLE handle, SQLSMALLINT type, const char* msg) {
    if (ret != SQL_SUCCESS && ret != SQL_SUCCESS_WITH_INFO) {
        SQLCHAR sqlState[6], message[1024];
        SQLINTEGER nativeError;
        SQLSMALLINT len;
        SQLGetDiagRec(type, handle, 1, sqlState, &nativeError, message, sizeof(message), &len);
        std::cerr << msg << ": " << message << std::endl;
    }
}

int main() {
    SQLHENV hEnv; SQLHDBC hDbc; SQLHSTMT hStmt;
    SQLRETURN ret;

    // 1. 分配環境句柄
    ret = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &hEnv);
    checkError(ret, hEnv, SQL_HANDLE_ENV, "AllocEnv");
    SQLSetEnvAttr(hEnv, SQL_ATTR_ODBC_VERSION, (void*)SQL_OV_ODBC3, 0);

    // 2. 分配連接句柄
    ret = SQLAllocHandle(SQL_HANDLE_DBC, hEnv, &hDbc);
    checkError(ret, hDbc, SQL_HANDLE_DBC, "AllocDbc");

    // 3. 連接 (使用 DSN)
    ret = SQLConnect(hDbc, (SQLCHAR*)"MyDSN", SQL_NTS, (SQLCHAR*)"user", SQL_NTS, (SQLCHAR*)"pwd", SQL_NTS);
    checkError(ret, hDbc, SQL_HANDLE_DBC, "Connect");

    // 4. 分配語句句柄並執行查詢
    SQLAllocHandle(SQL_HANDLE_STMT, hDbc, &hStmt);
    ret = SQLExecDirect(hStmt, (SQLCHAR*)"SELECT GETDATE()", SQL_NTS);
    checkError(ret, hStmt, SQL_HANDLE_STMT, "ExecDirect");

    // 5. 綁定列並提取
    SQL_TIMESTAMP_STRUCT ts;
    SQLLEN indicator;
    SQLBindCol(hStmt, 1, SQL_C_TYPE_TIMESTAMP, &ts, 0, &indicator);
    while (SQLFetch(hStmt) == SQL_SUCCESS) {
        std::cout << ts.year << "-" << ts.month << "-" << ts.day << " "
                  << ts.hour << ":" << ts.minute << ":" << ts.second << std::endl;
    }

    // 6. 清理
    SQLFreeHandle(SQL_HANDLE_STMT, hStmt);
    SQLDisconnect(hDbc);
    SQLFreeHandle(SQL_HANDLE_DBC, hDbc);
    SQLFreeHandle(SQL_HANDLE_ENV, hEnv);
    return 0;
}

方案二:SQL Server 原生 (ODBC Driver 17/18)

  • 連接字串:Driver={ODBC Driver 17 for SQL Server};Server=localhost;Database=Test;UID=sa;PWD=123;
  • 支援 Always Encrypted、資料分類、UTF-8

方案三:MySQL Connector/C++ (原生)

#include 
using namespace mysqlx;

int main() {
    try {
        Session sess("localhost", 33060, "user", "pwd");
        Schema db = sess.getSchema("test");
        Table table = db.getTable("users");
        RowResult res = table.select("id", "name").where("id > :id").bind("id", 10).execute();
        for (Row row : res.fetchAll()) {
            std::cout << row[0] << ": " << row[1] << std::endl;
        }
    } catch (const Error &e) {
        std::cerr << e.what() << std::endl;
    }
    return 0;
}

現代 C++ 封裝建議 (RAII + 連接池)

class DbConnection {
    SQLHDBC hDbc_;
public:
    DbConnection(const std::string& connStr) { /* SQLDriverConnect */ }
    ~DbConnection() { if (hDbc_) SQLDisconnect(hDbc_); }
    // 禁用拷貝,支援移動
    DbConnection(const DbConnection&) = delete;
    DbConnection& operator=(const DbConnection&) = delete;
    DbConnection(DbConnection&&) noexcept = default;
    // 執行查詢、參數綁定等封裝方法...
};

學習資源推薦

選型原則:跨平台/多資料庫選 ODBC,Windows 專用高效能選原生庫,避開 OLE DB。

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