C++ App (OTL/otlv4.h)
│
▼
unixODBC Driver Manager (libodbc.so)
│
▼
MySQL ODBC Driver (libmyodbc8w.so / libmyodbc8a.so)
│
▼
MySQL Server (TCP 3306 / Unix Socket)
關鍵點:OTL 僅是頭文件庫,編譯期綁定 ODBC API;運行期由 unixODBC 動態加載驅動,驅動再通過 MySQL 客戶端協議連接 Server。
cd /usr/local/src
wget https://www.unixodbc.org/unixODBC-2.3.11.tar.gz
tar -zxvf unixODBC-2.3.11.tar.gz
cd unixODBC-2.3.11
./configure --prefix=/usr/local/unixodbc --sysconfdir=/etc --enable-gui=no
make -j$(nproc) && make install
# 環境變量
echo 'export PATH=/usr/local/unixodbc/bin:$PATH' > /etc/profile.d/unixodbc.sh
echo 'export LD_LIBRARY_PATH=/usr/local/unixodbc/lib:$LD_LIBRARY_PATH' >> /etc/profile.d/unixodbc.sh
source /etc/profile.d/unixodbc.sh
# 驗證
odbcinst -j
# 輸出應顯示:
# DRIVERS............: /etc/odbcinst.ini
# SYSTEM DATA SOURCES: /etc/odbc.ini
# USER DATA SOURCES..: /root/.odbc.ini
cd /usr/local/src
wget https://dev.mysql.com/get/Downloads/Connector-ODBC/8.0/mysql-connector-odbc-8.0.33-linux-glibc2.12-x86-64bit.tar.gz
tar -zxvf mysql-connector-odbc-8.0.33-linux-glibc2.12-x86-64bit.tar.gz
cd mysql-connector-odbc-8.0.33-linux-glibc2.12-x86-64bit
# 手動註冊驅動(推薦,避免 myodbc-installer 依賴 Qt)
cat > /etc/odbcinst.ini <<'EOF'
[MySQL ODBC 8.0 Unicode Driver]
Description=MySQL ODBC 8.0 Unicode Driver
Driver=/usr/local/mysql-connector-odbc-8.0.33/lib/libmyodbc8w.so
Setup=/usr/local/mysql-connector-odbc-8.0.33/lib/libmyodbc8S.so
FileUsage=1
CPTimeout=30
CPReuse=120
Threading=3
EOF
# 複製驅動庫到系統庫路徑或配置 LD_LIBRARY_PATH
mkdir -p /usr/local/mysql-odbc/lib
cp lib/libmyodbc8w.so lib/libmyodbc8S.so /usr/local/mysql-odbc/lib/
echo '/usr/local/mysql-odbc/lib' > /etc/ld.so.conf.d/mysql-odbc.conf
ldconfig
cat > /etc/odbc.ini <<'EOF'
[MySQL_ODBC_DSN]
Description=MySQL Test DSN
Driver=MySQL ODBC 8.0 Unicode Driver
Server=127.0.0.1
Port=3306
Database=test_db
User=app_user
Password=AppPass@123
Charset=utf8mb4
Option=3
Socket=
EOF
# isql 測試(unixODBC 自帶)
isql -v MySQL_ODBC_DSN
# 成功進入 SQL 交互提示符:SQL>
# 也可用 odbcinst 檢查驅動註冊
odbcinst -q -d -n "MySQL ODBC 8.0 Unicode Driver"
#define OTL_ODBC_UNIX // 必須在包含 otlv4.h 前定義
#include
#include
int main() {
otl_connect db;
try {
db.rlogon("DSN=MySQL_ODBC_DSN"); // 或 "UID=app_user;PWD=AppPass@123;DSN=MySQL_ODBC_DSN"
std::cout << "Connected!" << std::endl;
otl_stream stm(50, "SELECT id, username FROM user WHERE status=1", db);
int id; std::string username;
while (!stm.eof()) {
stm >> id >> username;
std::cout << id << "\t" << username << std::endl;
}
db.logoff();
} catch (otl_exception& e) {
std::cerr << "OTL Error: " << e.msg << std::endl;
std::cerr << "SQL: " << e.stm_text << std::endl;
std::cerr << "Var: " << e.var_info << std::endl;
}
return 0;
}
g++ -std=c++11 -I/usr/local/unixodbc/include -I. \
-L/usr/local/unixodbc/lib -lodbc \
main.cpp -o test_otl
| 現象 | 原因/解決 |
|---|---|
Data source name not found | DSN 名稱拼寫錯誤、odbc.ini 路徑不匹配(檢查 odbcinst -j 輸出的 SYSTEM DATA SOURCES)。 |
Driver's SQLAllocHandle on SQL_HANDLE_HENV failed | 驅動庫依賴缺失(ldd /usr/local/mysql-odbc/lib/libmyodbc8w.so 檢查),補裝 libaio、openssl-libs。 |
| 中文亂碼 | DSN 加 Charset=utf8mb4,或連接後執行 SET NAMES utf8mb4。 |
OTL 編譯報 sql.h not found | 未安裝 unixODBC-devel 或 include 路徑未加,-I/usr/local/unixodbc/include。 |
| 64 位程序加載 32 位驅動失敗 | 確保 unixODBC、MySQL ODBC、OTL 應用全為 64 位(或全 32 位)。 |
std::vector 池,或用 CPTimeout/CPReuse 讓 unixODBC 內部池化。otl_stream 參數化查詢,防注入且複用執行計劃。Trace=Yes TraceFile=/var/log/odbc.log(僅調試期)。