title | tags | author | slide |
---|---|---|---|
WindowsでSQL*Plusを使う |
oracle 文字化け Windows |
dameyodamedame |
false |
WindowsでSQL*Plusを使う記事でchcpを勧めている記事がいくつかあり、最近も見かけてコメントしたら消えてしまったので、少し書いておこうかと思います。
例) https://qiita.com/bearbutler/items/a46b1c51aa74e2c99e7d
個人的にはあまりオススメしないので。
まずはとあるホストhost_aでサービス名xepdb1という名前のoracleが動いているとします。そこにWindowsPCからSQL*Plusを使って接続してDB操作をしようという話です。ここでは以前書いた記事の環境にWindowsから繋ぐ想定で説明します。
https://qiita.com/dameyodamedame/items/4ab7a2c595bb1c00f53e#oracle
https://www.oracle.com/jp/database/technologies/instant-client/winx64-64-downloads.html
ここにある最新のOracleクライアントのBasicパッケージとSQL*Plus パッケージをダウンロードして、zipを展開し、同じ名前のフォルダ(instantclient_バージョン番号)を統合してどこかに展開します(ここではC:\instantclient_21_9
とします)。
コマンドプロンプトを起動して以下の操作をします。
C:\>cd instantclient_21_9
C:\instantclient_21_9>sqlplus SYSTEM/pass@host_a/xepdb1
SQL*Plus: Release 21.0.0.0.0 - Production on xxx
Version 21.9.0.0.0
Copyright (c) 1982, 2022, Oracle. All rights reserved.
Last Successful login time: xxx
Connected to:
Oracle Database 21c Express Edition Release 21.0.0.0.0 - Production
Version 21.3.0.0.0
SQL> select 'ほげ' from dual;
'????'
------------
????
SQL> exit
Disconnected from Oracle Database 21c Express Edition Release 21.0.0.0.0 - Production
Version 21.3.0.0.0
selectの結果が化けていますね。
「sqlplus 文字化け site:.oracle.com」でGoogle検索(日本語)すると
https://docs.oracle.com/cd/E57425_01/121/SQPUG/GUID-E26A730D-C5B1-4CB3-BB2F-07E526B547C0.htm
が出てきます。つまりWindowsでは環境変数NLS_LANGを、Japanese_Japan.JA16SJIS
にする必要があるということです(Japanese_Japan.JA16SJISTILDEが良いとする資料もありましたが、Oracleから明示的に推されている資料を見つけられませんでした)。個人的にはJapanese_Japan.JA16SJISTILDEの方が良いと思います(理由などは以下に記載されています)が、本記事内ではJapanese_Japan.JA16SJISで統一しています。
https://www.idearu.info/article/data/ds1083
c:\instantclient_21_9>set NLS_LANG=Japanese_Japan.JA16SJIS
c:\instantclient_21_9>sqlplus.exe SYSTEM/pass@localhost/xepdb1
SQL*Plus: Release 21.0.0.0.0 - Production on xxx
Version 21.9.0.0.0
Copyright (c) 1982, 2022, Oracle. All rights reserved.
最終正常ログイン時間: xxx
Oracle Database 21c Express Edition Release 21.0.0.0.0 - Production
Version 21.3.0.0.0
に接続されました。
SQL> select 'ほげ' from dual;
'ほげ'
------------
ほげ
SQL> exit
Oracle Database 21c Express Edition Release 21.0.0.0.0 - Production
Version 21.3.0.0.0との接続が切断されました。
メッセージが日本語で表示されるようになり、select結果の文字化けもなくなりました。
紹介されている方法は上記現象の対策として以下を実施します。
- 環境変数NLS_LANGにJapanese_Japan.UTF8を設定
- chcp 65001を実施
c:\instantclient_21_9>set NLS_LANG=Japanese_Japan.UTF8
c:\instantclient_21_9>chcp 65001
Active code page: 65001
c:\instantclient_21_9>sqlplus.exe SYSTEM/pass@localhost/xepdb1
SQL*Plus: Release 21.0.0.0.0 - Production on xxx
Version 21.9.0.0.0
Copyright (c) 1982, 2022, Oracle. All rights reserved.
最終正常ログイン時間: xxx
Oracle Database 21c Express Edition Release 21.0.0.0.0 - Production
Version 21.3.0.0.0
に接続されました。
SQL> select 'ほげ' from dual;
'@@'
------
@@
SQL> exit
Oracle Database 21c Express Edition Release 21.0.0.0.0 - Production
Version 21.3.0.0.0との接続が切断されました。
メッセージなどの日本語は大丈夫ですが、肝心のselect結果が化けてしまっています。
PS C:\instantclient_21_9> $Env:NLS_LANG = "Japanese_Japan.UTF8"
PS C:\instantclient_21_9> .\sqlplus.exe SYSTEM/pass@localhost/xepdb1
SQL*Plus: Release 21.0.0.0.0 - Production on xxx
Version 21.9.0.0.0
Copyright (c) 1982, 2022, Oracle. All rights reserved.
最終正常ログイン時間: xxx
Oracle Database 21c Express Edition Release 21.0.0.0.0 - Production
Version 21.3.0.0.0
に接続されました。
SQL> select 'ほげ' from dual;
'��'
------------------
��
SQL> exit
Oracle Database 21c Express Edition Release 21.0.0.0.0 - Production
Version 21.3.0.0.0との接続が切断されました。
コマンドプロンプトと同様メッセージなどの日本語は大丈夫ですが、肝心のselect結果が化けてしまっています。
対策不十分です。
Japanese_Japan.JA16SJISは名前のとおりシフトJISしか使えず、例えばハングル文字の안녕하십니까
には該当コードがありません。Japanese_Japan.AL32UTF8にするとUTF-8が使えるようになり、これらの文字も使える
のですが、コマンドプロンプトやPowerShellの端末のデフォルト設定では(コードページが932=シフトJISなので)これらの文字を表示することが出来ません。この設定を変えるコマンドがchcpで、
https://learn.microsoft.com/ja-jp/windows-server/administration/windows-commands/chcp
65001はutf-8を表しています。
https://learn.microsoft.com/ja-jp/windows/win32/intl/code-page-identifiers
なので、oracleが返したUTF-8のコードはここで調べた範囲では正しく表示できています。
端末からUTF-8のつもりで読み込んだコードが正しくOracleに伝わっていないからです。例えば先程のselect文を以下に変更すると表示できます。
SQL> select unistr('\307b\3052') as str from dual;
STR
--------
ほげ
SQL>
リダイレクトやパイプを使うことです。これらを使えば端末のエンコーディング設定に煩わされることがありません。事前にUTF-8で書かれたSQLファイルを用意します。
select 'ほげ' from dual;
C:\instantclient_21_9>sqlplus.exe SYSTEM/pass@localhost/xepdb1 <hoge.sql
SQL*Plus: Release 21.0.0.0.0 - Production on xxx
Version 21.9.0.0.0
Copyright (c) 1982, 2022, Oracle. All rights reserved.
最終正常ログイン時間: xxx
Oracle Database 21c Express Edition Release 21.0.0.0.0 - Production
Version 21.3.0.0.0
に接続されました。
SQL>
'ほげ'
------
ほげ
SQL> Oracle Database 21c Express Edition Release 21.0.0.0.0 - Production
Version 21.3.0.0.0との接続が切断されました。
ただどうせリダイレクトするなら、出力もリダイレクトでいいわけで…
C:\instantclient_21_9>sqlplus.exe SYSTEM/pass@localhost/xepdb1 <hoge.sql >hoge.log
そうなると端末の設定など意味がないので、chcpもする必要がなくなります(unicodeを扱いたいならAL32UTF8の設定だけは必要です)。
さきほどのハングルやサロゲートペアになる絵文字まで試すと…
select 'ほげ' from dual;
select '안녕하십니까' from dual;
select '😀' from dual;
C:\instantclient_21_9>sqlplus.exe SYSTEM/pass@localhost/xepdb1 <hoge2.sql >hoge2.log
SQL*Plus: Release 21.0.0.0.0 - Production on xxx
Version 21.9.0.0.0
Copyright (c) 1982, 2022, Oracle. All rights reserved.
最終正常ログイン時間: xxx
Oracle Database 21c Express Edition Release 21.0.0.0.0 - Production
Version 21.3.0.0.0
に接続されました。
SQL>
'ほげ'
------
ほげ
SQL>
'안녕하십니까'
------------------
안녕하십니까
SQL>
'😀'
----
😀
SQL> Oracle Database 21c Express Edition Release 21.0.0.0.0 - Production
Version 21.3.0.0.0との接続が切断されました。
問題ないようです。ただし、
https://www.oracle.com/jp/database/technologies/faq-nls-lang.html
WindowsにOracle Unicodeクライアントはありますか。 ... Oracleデータベースに含まれるUnicode対応のクライアントは、iSQL*Plusのみです。 ...
- 現状Windowsでは原則シフトJISで動作させるのが好ましそう
- Unicode文字が必要ならUTF-8もありだが、chcpでは入力が出来ないので注意
- FAQによると(Windowsの)
Oracleデータベースに含まれるUnicode対応のクライアントは、iSQL*Plusのみ
とのこと
個人的にシフトJIS推しなわけではありません。Oracleもそうで、MSのせいで仕方ないという体に見えます。MSはMSで互換性、引いてはユーザーのために仕方なくと言いそうな気もします。いつかシステムロケールがUTF-8になって至るところが燃え上がる(?)まではこの状況が続きそうなので、いざというとき火を吹かないよう、確実な部分を見極めつつ徐々に対応していくべきだと思います。