【2017/06/05追記】
本現象は先日出た累積更新(KB4020102)で解消されています。
【追記ここまで】
きっかけは @masaru_b_cl さんのこのツイートから。
SQL*Plusが出力する日本語が、Windows 10の新コンソールだと文字化けする……なんだこれ?
— 白い高野さん (@masaru_b_cl) 2017年5月26日
手元の環境でこの現象が再現して回避策を見つけることができたのでここにメモっておきます。
環境について
今回、以下の環境で文字化けが起きることを確認しました。
クライアント
- 64Bit版 Windows 10 Pro / Creators Update(1703)
- 今月の更新まで適用済み
- Oracle Instant Client for Microsoft Windows (x64) 12.2.0.1.0
Instant Client Package - Basic
Instant Client Package - SQL*Plus
をインストールしてSQL*Plusを実行可能に設定
- NLS_LANG =
Japanese_Japan.JA16SJISTILDE
- 64Bit版 Windows 10 Pro / Creators Update(1703)
サーバー
- Windows Server 2012 R2
- Oracle Database Enterprise Edition 12.1.0.2.0
- データベースのキャラクタセット =
JA16SJISTILDE
テスト用にTEST_TABLE
テーブルを用意し、投入したデータは以下の様な感じです。
現象の確認
とりあえずデータベースに接続して以下のクエリを流してみます。
SELECT VALUE FROM TEST_TABLE ORDER BY KEY;
結果はこんな感じで思いっきり日本語が化けます。
よく見るとログイン時のメッセージも化けています。
ちなみにPowerShellからSQL*Plusを実行しても同じ感じになります。
原因と回避策
原因はCreators Updateで仕込まれたバグの様です。
新コンソールはマルチバイト文字のハンドリングにBUGがあるらしく。 https://t.co/JxEBWlBOS2 Creators Update ではBUGったまま出荷されている模様。最新のIPでは直っています。マイケルに期待している
— Takekazu Omi (@takekazuomi) 2017年5月26日
@takekazuomi さん曰く最新のInsider Previewではこの現象は改善されているそうなので、しばらく我慢すればパッチも出るんじゃないかと思います。
とりあえず現状としては以下の回避策で対処することが可能です。
追記. 従来のコンソールを使う
本エントリを公開した瞬間に@takekazuomi さんよりコメント頂きました。
これでは回避できませんか? pic.twitter.com/pwDhI97QxU
— Takekazu Omi (@takekazuomi) 2017年5月26日
コマンドプロンプトのプロパティで従来のコンソールを使う
にチェックを入れてコマンドプロンプトを再起動することで本現象を回避することができました。
この方法が一番手っ取り早く確実ですね。
私の調査は一体何だったのかという気持ちでいっぱいですが気にしないことにします....
1. 先頭にダミーカラムを追加する
この現象はコンソールに表示される最初の文字が日本語でなければ良いっぽく、
SELECT '', VALUE FROM TEST_TABLE ORDER BY KEY;
な感じで先頭にダミーカラムを付けて最初にスペースが表示される様にするだけでも問題は解決します。
とりあえずこれで問題は回避できますが、非常にトホホな気分になります...
2. クライアントの文字セットをUTF8にする
真っ当な回避策としてはクライアント側の文字セットをユニコードにしてしまう方法があります。
今回はUTF8に変更することで対処してみます。
NLS_LANG
の文字セットをAL32UTF8
に変えればクライアント側の文字コードをUTF8にできます。
これだけだとコマンドプロンプトで文字を表示できないのでCHCP
コマンドでコードページも変える必要があります。
実行するコマンドは以下の様な感じになります。
CHCP 65001 SET NLS_LANG=Japanese_Japan.AL32UTF8
この状態であれば下図の様に文字化けを回避することができます。
ちなみにPowerShellであれば、CHCP
コマンドの代わりに[Console]::OutputEncoding
の設定を変えることでも対応可能です。
[Console]::OutputEncoding=[Text.Encoding]::UTF8 $env:NLS_LANG='Japanese_Japan.AL32UTF8'
最後に
残念の一言につきるので早く修正パッチが提供されることを望みます。