AccessとMySQL(UTF-8)をODBC接続

Access を MySql サーバーのフロントエンドにしてシステム開発することになった。PHPで構築したシステムを流用するので、MySqlのデータベースはエンコーディング UTF-8 で構成したい。

ネットで検索するとMySql ODBC と MySql のエンコード設定に関していろいろな情報があり、これはと思うものを試すうちに期待通りに動作した方法を紹介します。

サーバー側設定

1. MySQL Server の my.cnf の設定

characterset が UTF-8 でサーバーを構成。

[mysqld]
... 一部省略 ...
# default encoding
character-set-server=utf8
skip-character-set-client-handshake

[mysql]
default-character-set=utf8

[client]
default-character-set=utf8

2. mysql コンソールから show variables の結果
MySQL サーバーを再起動して、mysql コンソールで接続。

mysql> show variables like '%char%';
+--------------------------+----------------------------+
| Variable_name            | Value                      |
+--------------------------+----------------------------+
| character_set_client     | utf8                       |
| character_set_connection | utf8                       |
| character_set_database   | utf8                       |
| character_set_filesystem | binary                     |
| character_set_results    | utf8                       |
| character_set_server     | utf8                       |
| character_set_system     | utf8                       |
| character_sets_dir       | /usr/share/mysql/charsets/ |
+--------------------------+----------------------------+

characterset が UTF-8 になっているのを確認

3. テーブル作成
テーブルは DEFAULT CHARSET=utf8 で作成する。

CREATE TABLE Bar (
...
} ENGINE=InnoDB DEFAULT CHARSET=utf8;

4. ファイアウォールの設定
TCP ポート3306 へのアクセスを許可する設定に変更します。

クライアント側設定

1. MySQL Connector/ODBC をダウンロード
http://dev.mysql.com/downloads/connector/odbc/ から Connector/ODBC 5.3.4 の 「Windows (x86, 32-bit), MSI Installer」または、「Windows (x86, 64-bit), MSI Installer」をダウンロードして、インストーラーを起動してインストール。

※ Windows 8/8.1 では Microsoft Visual C++ 2010 Redistributable Package を事前にインストールしておかないと MySQL Connector/ODBCのインストールが失敗してしまうので、以下からダウンロードしてインストールしておきます。

32ビット版:https://www.microsoft.com/en-gb/download/confirmation.aspx?id=5555
64ビット版:https://www.microsoft.com/en-us/download/confirmation.aspx?id=14632

2. ODBC DSN の作成
Access から接続するために DSN を作成します。

-「コントロール パネル\システムとセキュリティ\管理ツール」から「データソース(ODBC)」をダブルクリック
– 「データ ソースの新規作成」で「MySQL ODBC 5.3 Unicode Driver」を選択
mysql-odbc-driver
– Data Source Name, TCP/IP Server, User, Password, Database を入力
mysql-odbc-conn
(Character Set と Initial Statement は空のまま、何も指定していません。)

3. Access からリンクテーブル
Access からリンクテーブルを上記のDSNを使って作成して、データを表示、編集し、また同テーブルのデータをPHPで作成したプログラムで操作しましたが、双方で問題なし。

PHP fputcsvで出力するとダブルクォーテーションで括られる

PHP のfputcsvは配列データをCSVファイルへ出力する際に自動でエスケープ処理もしてくれるので便利ですが、エンコーディングを UTF-8 から Shift-JIS へ変換して出力すると、文字列が予期せずダブルクォーテーションで括られる場合があります。

<?php
function convertEnc($arg) {
    if (is_array($arg)) {
        return array_map('convertEnc', $arg);
    } else {
        return mb_convert_encoding($arg, "SJIS-win", "UTF-8");
    }
}

$array = array(
              "あ"
             ," "
             ,"\r\n"
             ,"ソ"
             ,"十"
);
$fp = fopen("php://stdout", "w");

// UTF-8 のまま出力
fputcsv($fp, $array);

// Shift-JIS に変換して出力
//fputcsv($fp, convertEnc($array));

fclose($fp);
?>

// UTF-8 出力結果
UTF-8 のままで出力すると改行コードだけがダブルクォーテーションで囲まれます。

あ," ","
",ソ,十

// Shift-JIS 出力結果
Shift-JIS へ出力すると「ソ」、「十」もダブルクォーテーションで囲まれてしまいます。

あ," ","
","ソ","十"

「ソ」、「十」は Shift-JIS では、れぞれ「0x8F5C」、「0x835C」で 0x5C はバックスラッシュ、バックスラッシュはエスケープ文字扱いなのでダブルクォーテーションで囲まれるようです。

参考:
https://github.com/php/php-src/blob/master/ext/standard/file.c

		/* enclose a field that contains a delimiter, an enclosure character, or a newline */
		if (FPUTCSV_FLD_CHK(delimiter) ||
			FPUTCSV_FLD_CHK(enclosure) ||
			FPUTCSV_FLD_CHK(escape_char) ||
			FPUTCSV_FLD_CHK('\n') ||
			FPUTCSV_FLD_CHK('\r') ||
			FPUTCSV_FLD_CHK('\t') ||
			FPUTCSV_FLD_CHK(' ')
		) {