chcp 65001 すると MySQLが日本語を受け付けてくれない

環境-1つめ：10.1.32-MariaDB , XAMPP v3.2.2 , Windows10 Enterprise
環境-2つめ：10.4.17-MariaDB , XAMPP v3.2.4 , Windows10 PRO

結論から書くと私の場合は chcp 65001 を使ってWindowsコマンドプロンプト上から utf-8 の入力をするのは避けたほうがいい気がする。となりました。

##起こったこと

+ Windowsコマンドプロンプトから MySQL を操作する時、`chcp 65001` でコマンドプロンプトの文字コードを utf-8 にすると MySQL が日本語（3バイトuft-8）を*受け付けてくれない*。
+ 読み出し時の文字化けはない。
+ また `chcp 932` のまま、MySQL内で `set names cp932` をすればなにも問題は起きない。
+ ふたつの環境で再現する。



```
# chcp 65001
///// ウィンドウが変わる
Active code page: 65001

# mysql -u root -p

MariaDB [(none)]> USE db1
Database changed

///// insert を試みる
MariaDB [db1]> INSERT INTO tb10(num,name) VALUES(1,'佐藤');
    '>
    '>
    '>　　　　　///// ← 処理が完了していない
    '> ;　　　　///// ← セミコロン入れても完了しない
    '>
    '> '　　　　///// ← よく見るとシングルクオーテーション抜けだと言われてるので入力する
    ->
    -> ;　　　　///// ← セミコロンを入れて完了しエラー文が出る
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '' at line 1

```

この挙動は insert だけではなく as句 による名付けや、他の構文内で日本語を使った場合でもほぼ変わらない。
（as句だとシングルクオーテーションのありなしで少し変わる）

```
MariaDB [db1]> SELECT name AS '名前' FROM tb10;
    '> '
    -> ;
ERROR 1054 (42S22): Unknown column 'name' in 'field list'

MariaDB [db1]> SELECT name AS 名前 FROM tb10;
    -> ;
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '' at line 1

MariaDB [db1]> SELECT ROD('あ');
    '> '
    -> ;
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '' at line 1

```

#####直接文字コードを書くことによる insert はできる
utf-8 を CHAR()関数によって変換することはできる。
また直接文字コードを書くことによる insert もできる。

```
MariaDB [db1]> SELECT CHAR(0xe38182 using utf8);
+---------------------------+
| CHAR(0xe38182 using utf8) |
+---------------------------+
| あ                        |
+---------------------------+
1 row in set (0.000 sec)

MariaDB [db1]> INSERT INTO tb10(num,name) VALUES(1,0xe38182e38184);
Query OK, 1 row affected (0.00 sec)

MariaDB [db1]> SELECT * FROM tb10;
+------+--------+
| num  | name   |
+------+--------+
|    1 | あい   |
+------+--------+
1 row in set (0.000 sec)
```

#####接続が utf8 でカラムが utf8 のとき、4bit文字が現れるとそこで文字が切れる現象を思い出す
参考：https://tmtms.hatenablog.com/entry/2016/09/06/mysql-utf8

日本語の後ろが読まれてないのでは？ というわけで日本語の末尾から行を分けてinsertしてみる。


```
MariaDB [db1]> insert into tb10(num,name) values(3,'佐藤
    '> ');　　　　　　　　　　　　　　　　　///// 『 '); 』を改行してから入力する
Query OK, 1 row affected (0.011 sec)

MariaDB [db1]> select * from tb10;
+------+--------+
| num  | name   |
+------+--------+
|    1 | あい   |
|    2 | 鈴木   |
|    3 |
      |
+------+--------+
3 rows in set (0.000 sec)
```
受け付けてくれた。
……なんかおかしいけど。
ただinsertできたらこっちのもので出力させます。


```
MariaDB [db1]> SELECT * FROM tb10 INTO OUTFILE 'a.dmp';
Query OK, 3 rows affected, 1 warning (0.001 sec)
```
これをテキストと16進数とでそれぞれ見て……

```
>type a.dmp
1       あい
2       鈴木
3       \


>certutil -f -encodehex a.dmp a_16.txt 4　　　　///// 16進数への変換
Input Length = 12
Output Length = 38
CertUtil: -encodehex command completed successfully.

>type a_16.txt
31 09 e3 81 82 e3 81 84  0a 32 09 e9 88 b4 e6 9c
a8 0a 33 09 5c 0a 0a
```

うん…………？

ちょっとわかりにくいので、新しく tb11 を作り2回insertします。

```
MariaDB [db1]> CREATE TABLE tb11(text VARCHAR(100));　　　///// テーブルの作成から
Query OK, 0 rows affected (0.007 sec)

MariaDB [db1]> INSERT INTO tb11(text) VALUES('あい
    '> ');
Query OK, 1 row affected (0.003 sec)

MariaDB [db1]> INSERT INTO tb11(text) VALUES('高橋
    '> ');
Query OK, 1 row affected (0.001 sec)

MariaDB [db1]> SELECT * FROM tb11;
+------+
| text |
+------+
|
    |
|
    |
+------+
2 rows in set (0.000 sec)

MariaDB [db1]> SELECT * FROM tb11 INTO OUTFILE 'b.dmp';　　　///// 出力する
Query OK, 2 rows affected, 1 warning (0.002 sec)
```
それをまたテキストファイルと16進数とで見て

```
>type b.dmp
\

\


>type b_16.txt
5c 0a 0a 5c 0a 0a
```

うん…………。
`0a`=`<LF>` の改行がひとつ多く入ってるのはシングルクォーテーションの間で一度改行してるのを正しく反映していると言えます。
その前、どんな文字を入れても `5c` になってるのは、ちょっとわからない。
（BOM も疑ったけどBOMは `EF BB BF` だからいまいちそれと確信持てない……）

と、ここでお手上げになりました。



##以下はMySQLの設定の確認
MySQL側の文字コードは utf-8 で統一されている（はず）


#####character_set の確認

```
MariaDB [(none)]> show global variables like 'char%';
+--------------------------+----------------------------------------------------------------+
| Variable_name            | Value                                                          |
+--------------------------+----------------------------------------------------------------+
| character_set_client     | utf8mb4                                                        |
| character_set_connection | utf8mb4                                                        |
| character_set_database   | utf8mb4                                                        |
| character_set_filesystem | binary                                                         |
| character_set_results    | utf8mb4                                                        |
| character_set_server     | utf8mb4                                                        |
| character_set_system     | utf8                                                           |
| character_sets_dir       | C:\ <--中略--> mysql\share\charsets\ |
+--------------------------+----------------------------------------------------------------+
8 rows in set (0.001 sec)

MariaDB [(none)]> show session variables like 'char%';
+--------------------------+----------------------------------------------------------------+
| Variable_name            | Value                                                          |
+--------------------------+----------------------------------------------------------------+
| character_set_client     | utf8mb4                                                        |
| character_set_connection | utf8mb4                                                        |
| character_set_database   | utf8mb4                                                        |
| character_set_filesystem | binary                                                         |
| character_set_results    | utf8mb4                                                        |
| character_set_server     | utf8mb4                                                        |
| character_set_system     | utf8                                                           |
| character_sets_dir       | C:\ <--中略--> mysql\share\charsets\ |
+--------------------------+----------------------------------------------------------------+
8 rows in set (0.000 sec)
```

#####その上で作られた db1 

```
MariaDB [(none)]> select * from INFORMATION_SCHEMA.SCHEMATA where SCHEMA_NAME='db1';
+--------------+-------------+----------------------------+------------------------+----------+
| CATALOG_NAME | SCHEMA_NAME | DEFAULT_CHARACTER_SET_NAME | DEFAULT_COLLATION_NAME | SQL_PATH |
+--------------+-------------+----------------------------+------------------------+----------+
| def          | db1         | utf8mb4                    | utf8mb4_unicode_ci     | NULL     |
+--------------+-------------+----------------------------+------------------------+----------+
1 row in set (0.002 sec)
```

#####その上で作られた tb10

```
MariaDB [db1]> show create table tb10;
+-------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table                                                                                                                                                                         |
+-------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| tb10  | CREATE TABLE `tb10` (
  `num` int(11) DEFAULT NULL,
  `name` varchar(100) COLLATE utf8mb4_unicode_ci DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci |
+-------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.000 sec)
```

#####一応 my.ini の記述も置いておきます

```
[mysqld]
## UTF 8 Settings
init-connect='SET NAMES utf8mb4'
collation_server=utf8mb4_unicode_ci
character_set_server=utf8mb4
skip-character-set-client-handshake
character_sets-dir="C:/ <--中略--> mysql/share/charsets"
sql_mode=NO_ZERO_IN_DATE,NO_ZERO_DATE,NO_ENGINE_SUBSTITUTION
log_bin_trust_function_creators = 1

[mysqldump]
default-character-set	= utf8mb4

[mysql]
default-character-set	= utf8mb4

```
##Shift_JIS のまま set names すれば問題は起きない

```
# chcp
現在のコード ページ: 932

# mysql -u root -p

MariaDB [(none)]> SET NAMES cp932;
Query OK, 0 rows affected (0.000 sec)

MariaDB [(none)]> USE db1
Database changed

MariaDB [db1]> INSERT INTO tb10(num,name) VALUES(2,'鈴木');
Query OK, 1 row affected (0.003 sec)

MariaDB [db1]> SELECT * from tb10;
+------+------+
| num  | name |
+------+------+
|    1 | あい     |
|    2 | 鈴木     |
+------+------+
2 rows in set (0.003 sec)

```



怪しいのは chcp 65001 かな…………

コマンドラインから MySQL に渡している文字列を16進数で抜き出す(どこかに出力させる)ことができればもう少しわかりそうなのですが。