MS-Windows 上の Xojo で MySQL データベースに接続すると日本語の扱いに問題が出る


環境

  • クライアント Windows 10 Pro バージョン 20H2 + Xojo 2019 r3.1 および Xojo 2019 r3.2
  • データベースサーバ Ubuntu 18.04 AMD64 および Ubuntu 20.04 AMD64 + ディストリビューション付属の MariaDB を MySQL として動かす

MySQL (MariaDB) データベースの設定:

  • character-set-server = utf8mb4
  • collation-server = utf8mb4_bin

データベース

以下のように、英語のフィールド名を持つ sensorテーブルと 日本語のフィールド名を持つ sensorJP テーブルを作る。


MariaDB [(none)]> use test;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
MariaDB [test]> select * from sensor;
+----+--------+------+------+
| id | sensor | temp | hemi |
+----+--------+------+------+
| 1 | 1 | 22 | 85 |
| 2 | 1 | 24.3 | 77 |
| 3 | 1 | 8.6 | 60 |
+----+--------+------+------+
3 rows in set (0.14 sec)

MariaDB [test]> select * from sensorJP;
+----+--------+--------+--------+
| id | sensor | 温度 | 湿度 |
+----+--------+--------+--------+
| 1 | 1 | 22 | 85 |
| 2 | 1 | 24.3 | 77 |
| 3 | 1 | 8.6 | 60 |
| 4 | 2 | 34.1 | 90 |
+----+--------+--------+--------+
4 rows in set (0.13 sec)

MS-Windows 上の Xojo で MySQL データベースに接続すると日本語の扱いに問題が出る。


If app.db.Connect Then
app.db.SQLExecute("set names utf8")
app.db.SQLExecute("set character set utf8")
Try
app.db.ExecuteSQL("DROP TABLE sensor20200730")
Catch err As DatabaseException
End Try
Try
app.db.ExecuteSQL("DROP TABLE sensor20200730JP")
Catch err As DatabaseException
End Try

app.db.ExecuteSQL("CREATE TABLE sensor20200730 (id INT NOT NULL, temp INT, hemi INT, memo INT)")
app.db.ExecuteSQL("INSERT INTO sensor20200730 (id, temp, hemi, memo) VALUES (1,2,3,4)")

Var rows As RowSet = app.db.SelectSQL("select * from sensor20200730")
rows.MoveToFirstRow
For Each row As DatabaseRow In Rows
Listbox1.AddRow(row.column("id").StringValue, row.column("temp").stringvalue, row.column("hemi").StringValue, row.column("memo").StringValue.DefineEncoding(Encodings.UTF8))
Next


app.db.ExecuteSQL("CREATE TABLE sensor20200730JP (id INT NOT NULL, 温度 INT, 湿度 INT, memo INT)")
app.db.ExecuteSQL("INSERT INTO sensor20200730JP (id, 温度, 湿度, memo) VALUES (1,2,3,4)")

Var rowsJP As RowSet = app.db.SelectSQL("select * from sensor20200730JP")
rowsJP.MoveToFirstRow
For Each rowJP As DatabaseRow In RowsJP
Listbox2.AddRow(rowJP.column("id").StringValue, rowJP.column("温度").stringvalue, rowJP.column("湿度").StringValue, rowJP.column("memo").StringValue.DefineEncoding(Encodings.UTF8))
Next


Else
Msgbox "Could not connect"
End If

ここで、以下にはエラーが出ない。


Listbox1.AddRow(row.column("id").StringValue, row.column("temp").stringvalue, row.column("hemi").StringValue, row.column("memo").StringValue.DefineEncoding(Encodings.UTF8))

以下の行でエラーが出る


Listbox2.AddRow(rowJP.column("id").StringValue, rowJP.column("温度").stringvalue, rowJP.column("湿度").StringValue, rowJP.column("memo").StringValue.DefineEncoding(Encodings.UTF8))

Variablesを確認すると、SELECTで取得した結果が文字化けしていることがわかる。

解決策

Xojo の Windows 上の MySQL ドライバのバグであり、修正待ち(Feedback #60768)であるが、2021/03/07現在進捗が無い。

Xojo の Linux 版だとこの問題が発生しない。しかしながら Linux 上で開発するのも無理がある。
Linux だと Xojo IDE が日本語の扱いに問題が出るためである。

なので Windows上で開発して、デバッグ実行などはLinuxにリモート実行の機能を使うということになってしちめんどくさい。
あるいは OSX 上だと問題が無いのかな?

変則的な解決策として、Windowsのロケールを UTF-8 にしてしまうという技がある。
「Windows 10 の 日本語ロケールを CP932 から UTF-8 にする」
https://qiita.com/nanbuwks/items/8d6c5685b1d4d70c058b
これだと上記の問題は出ない。