⛵
AlmaLinux9でMySQL connector for unixODBCをビルドする
はじめに
AlmaLinux9でunixODBCを利用する必要が発生しました。
しかしrpmではel8までしかなかったのでソースからビルドすることにしました。
その際の手順となります。
ソースのダウンロード
- mysql-connector-odbc-8.0.30-src.tar.gz
- 以下のURLから取得
- Oracleからダウンロードなのでアカウントが必要
- 「Source Code」を選択
- 「All Operating Systems (Generic) (Architecture Independent), Compressed TAR Archive」を選択してダウンロードする。
- インストールするサーバ上に配置して展開する。
- 以下の例では/tmpに配置
mkdir -p /root/working
cd /root/working
dnf install -y tar
tar zxvf /tmp/mysql-connector-odbc-8.0.30-src.tar.gz
cd mysql-connector-odbc-8.0.30-src
ビルド手順
追加パッケージ
- 一部過不足あるかも?試行錯誤しながら実施したため
dnf install -y gcc g++ make
dnf --enablerepo=crb install -y mysql-devel
dnf --enablerepo=crb install -y unixODBC-devel
dnf --enablerepo=crb install -y libzstd-devel
dnf install -y zlib-devel
dnf install -y openssl-devel
dnf --enablerepo=crb install -y mysql-libs
ビルド & インストール
- インストール先は/usr/local/lib
- 参考ページ
cmake -G "Unix Makefiles" -DWITH_UNIXODBC=1 -DDISABLE_GUI=1
make
make install
unixODBCの設定
/etc/odbcinst.ini
- 次の内容で更新
[ODBC Drivers]
MyODBCw=Installed
MyODBCa=Installed
/usr/local/lib/libmyodbc8w.so=Installed
/usr/local/lib/libmyodbc8a.so=Installed
UsageCount=2
[MyODBCw]
Driver=/usr/local/lib/libmyodbc8w.so
Description=Unicode Driver for connecting to MySQL database server
Threading=0
UsageCount=2
[/usr/local/lib/libmyodbc8w.so]
Driver=/usr/local/lib/libmyodbc8w.so
Description=Unicode Driver for connecting to MySQL database server
Threading=0
UsageCount=2
[MyODBCa]
Driver=/usr/local/lib/libmyodbc8a.so
Description=ANSI Driver for connecting to MySQL database server
Threading=0
UsageCount=2
[/usr/local/lib/libmyodbc8a.so]
Driver=/usr/local/lib/libmyodbc8a.so
Description=ANSI Driver for connecting to MySQL database server
Threading=0
UsageCount=2
確認
odbcinst -q -d
/etc/odbc.ini
- 次の内容で更新
[MySQL_TEST1]
Driver = MyODBCw
Description = Test for MySQL 1
User = dbuser
Password = Pass@word1
Database = test_db
Server = xxx.xxx.xxx.xxx
Port = 3306
- ユーザ/パスワード/データベースは適宜変更
- 最初の[MySQL_TEST1]はDSNという名前付けで任意に変更可能
- DSNは利用する際に設定を選択するための文字列
- DSNを使用しない接続設定方法もある
確認
odbcinst -q -s
確認用MySQLの内容
- database名は「test_db」
- ユーザ名は「dbuser」
- パスワードは「Pass@word1」
- 参考ページ
ユーザとDATABASE作成
CREATE USER 'dbuser'@'%' IDENTIFIED BY 'Pass@word1';
CREATE DATABASE test_db;
GRANT ALL PRIVILEGES ON test_db.* TO 'dbuser'@'%';
FLUSH PRIVILEGES;
- mysql-connector-odbc-8.0.30では「WITH mysql_native_password」は不要
テーブル作成
test1_create.sql
CREATE TABLE `test1` (
`id` INT(10) NOT NULL AUTO_INCREMENT,
`v` VARCHAR(50) NULL DEFAULT NULL COLLATE 'utf8mb4_bin',
PRIMARY KEY (`id`) USING BTREE
)
COLLATE='utf8mb4_bin'
ENGINE=InnoDB
AUTO_INCREMENT=0
;
データのINSERT
test1_insert.sql
INSERT INTO `test1` (`id`, `v`) VALUES (1, 'TEST1');
INSERT INTO `test1` (`id`, `v`) VALUES (4, 'あああ');
INSERT INTO `test1` (`id`, `v`) VALUES (2, 'TEST2');
INSERT INTO `test1` (`id`, `v`) VALUES (3, 'TEST333');
動作確認 ・・・ python3
test1.py
import pyodbc
cnxn = pyodbc.connect('DSN=MySQL_TEST1')
cursor = cnxn.cursor()
cursor.execute("SELECT id,v FROM test1")
rows = cursor.fetchall()
for row in rows:
print(row.id, row.v)
実行結果
1 TEST1
2 TEST2
3 TEST333
4 あああ
動作確認 ・・・ c++
- pythonと同じSQLを実行
- 文字はutf8mb4_bin前提
test2.cpp
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sql.h>
#include <sqlext.h>
int main( int argc, char* argv[] )
{
SQLHENV env;
SQLHDBC dbc;
SQLHSTMT stmt;
SQLRETURN ret;
SQLSMALLINT columns;
int row = 0;
char sql[1024] = "";
sprintf(sql, "SELECT id,v FROM test1");
SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &env);
SQLSetEnvAttr(env, SQL_ATTR_ODBC_VERSION, (void *) SQL_OV_ODBC3, 0);
SQLAllocHandle(SQL_HANDLE_DBC, env, &dbc);
SQLDriverConnect(dbc, NULL, (SQLCHAR*)"DSN=MySQL_TEST1", SQL_NTS,NULL, 0, NULL, SQL_DRIVER_COMPLETE);
SQLAllocHandle(SQL_HANDLE_STMT, dbc, &stmt);
SQLExecDirect(stmt,(SQLCHAR*) sql, SQL_NTS);
SQLNumResultCols(stmt, &columns);
while (SQL_SUCCEEDED(ret = SQLFetch(stmt))) {
SQLUSMALLINT i;
printf("row[%d]\n", row);
for (i = 1; i <= columns; i++) {
SQLLEN len;
char buf[512];
memset(buf,0,sizeof(buf));
ret = SQLGetData(stmt, i, SQL_C_BINARY,buf, sizeof(buf), &len);
if (SQL_SUCCEEDED(ret)) {
printf(" items[%d]=`%s`\n", i - 1, buf);
}
}
row+=1;
}
return 0;
}
ビルド方法
gcc test2.cpp -lodbc -o test2
実行結果
row[0]
items[0]=`1`
items[1]=`TEST1`
row[1]
items[0]=`2`
items[1]=`TEST2`
row[2]
items[0]=`3`
items[1]=`TEST333`
row[3]
items[0]=`4`
items[1]=`あああ`
その他①・MySQL8で外部接続可能なrootの作成
- パスワードは適宜変更
CREATE USER 'root'@'%' IDENTIFIED BY 'kKv2z7x2pFHVA4h3sJTiFeKr';
GRANT all PRIVILEGES ON *.* TO 'root'@'%' WITH GRANT OPTION;
その他②・crb
- enablerepo=crbのcrbは「codeready-builder」の略
dnf config-manager --set-enabled crb
dnf install -y epel-release
その他③・SQL_C_BINARY
C++でマルチバイト文字を扱うときには常に悩みどころが存在します。
今回はutf8mb4_binで統一しているので、SQLGetDataのTargetType指定をSQL_C_BINARYとすることで、UTF-8のバイトデータが取得しています。
その他④・ODBCでSQLを発行するCLI
iusql MySQL_TEST1
Discussion