Ubuntu20.10でnanodbcからODBCの対応状況を確認する
Ubuntu というか Linux 環境で RDBMS 、特に SQL Server へ ODBC 接続していると、ついつい Windows 環境と同等な動作を期待してしまいます。
そもそも前提が異なるので完全互換は期待してません。
それでも、どの程度対応してるのかな?と思い立ったので、C++ ライブラリの nanodbc を利用して確認してみました。
環境
ODBC ドライバ
私の手元にある ODBC ドライバについて調査してみました。
ドライバ | SQL_DRIVER_NAME | SQL_DRIVER_VER | パッケージ |
---|---|---|---|
msodbc | libmsodbcsql-17.6.so.1.1 | 17.06.0001 | 公式サイト |
freetds | libtdsodbc.so | 01.02.0003 | tdsodbc |
mysql | libmyodbc8w.so | 08.00.0022 | 公式サイト |
maria | libmaodbc.so | 03.01.0009 | odbc-mariadb |
pg | psqlodbcw.so | 12.02.0000 | odbc-postgresql |
※表現の都合上、勝手にドライバに略名をつけてます。
調査結果
各ドライバの調査結果の一部を載せておきます。
パラメータ (sqlext.h) | msodbc | freetds | mysql | maria | pg |
---|---|---|---|---|---|
SQL_DRIVER_ODBC_VER | 03.52 | 03.50 | 03.80 | 03.51 | 03.51 |
SQL_ASYNC_MODE | 2 | 0 | 0 | 0 | 0 |
SQL_ACTIVE_CONNECTIONS | 0 | 0 | 0 | 0 | 0 |
SQL_ACTIVE_STATEMENTS | 1 | 1 | 0 | 0 | 0 |
SQL_ODBC_API_CONFORMANCE | 2 | 2 | 1 | 1 | 1 |
SQL_ODBC_SQL_CONFORMANCE | 1 | 1 | 1 | 1 | 1 |
SQL_MULT_RESULT_SETS | Y | Y | Y | Y | Y |
SQL_ACTIVE_ENVIRONMENTS | 0 | 0 | 0 | 0 | 0 |
SQL_SQL_CONFORMANCE | 1 | 1 | 4 | 4 | 1 |
SQL_MAX_ASYNC_CONCURRENT _STATEMENTS | 1 | 1 | 0 | 0 | core dump |
SQL_ODBC_INTERFACE _CONFORMANCE |
3 | 2 | 2 | 1 | 1 |
SQL_ATTR_ODBC_VERSION | 380 | 380 | 380 | 380 | 380 |
SQL_ATTR_AUTOCOMMIT | 1 | 1 | 1 | 4 | 1 |
unixODBC の SQL_ODBC_VER は 03.52 です。
SQL_ATTR_ODBC_VERSION が 3 ではなく 380 なのは、nanodbc の設定です。
残念ながら ODBC 3.8 の Driver-Aware Connection Pooling や 非同期通知等は使えないようです。
ソースコード
nanodbc::connection の get_info<T>() を利用すると手軽に情報を取得できます。
get_info<T>() は ODBC API の SQLGetInfo() を呼び出してます。
環境属性や接続属性を調査する場合は、ハンドルが用意されているので、
- SQLGetEnvAttr() には native_env_handle()
- SQLGetConnectAttr() には native_dbc_handle()
を指定すると情報を取得できます。
以下は、冗長な部分を省いたコードのサンプルです。
・ソースファイル (main.cpp)
・CMakeLists.txt
所感
当初、昔を思い出しながら SQLAllocHandle() で環境ハンドル用意して、SQLSetEnvAttr() で ODBC バージョン指定して、SQLAllocHandle() で接続ハンドル用意して...と、C で簡単なプログラムを書いて環境を調べました。
とりあえず目的は達成できたのですが、煩雑すぎて不満が募ります。
そこで、以前調査した nanodbc を使ってみたのですが、やっぱりお手軽です。
Poco や Qt5 より軽量と言うか薄い分、Win32API っぽいコーディングはやりやすいかも。