SQLclの文字化け対策(UTF-8で使う)

[SQLclの文字化け対策(MS932で使う)(https://qiita.com/madilloar/items/caf0c15fbeae8a2c591c)](https://qiita.com/madilloar/items/caf0c15fbeae8a2c591c)
でやったことのUTF-8版です。

コマンドプロンプトでも``chcp 65001``にすれば``UTF-8``が使えるのですが、サロゲートペア文字が文字化けしてしまいます。
``Windows Terminal``を使えばサロゲートペア文字もOKです。
あと、``login.sql``に``SET ENCODING UTF-8``を記述しないと文字化けます。


# Oracle DBサーバの文字コード確認
Oracle DBサーバの文字コードは``AL32UTF8``です。

```bat
SQL> select * from v$nls_parameters;

PARAMETER                  VALUE                            CON_ID
__________________________ _____________________________ _________
NLS_LANGUAGE               JAPANESE                              3
NLS_TERRITORY              JAPAN                                 3
NLS_CURRENCY               \                                     3
NLS_ISO_CURRENCY           JAPAN                                 3
NLS_NUMERIC_CHARACTERS     .,                                    3
NLS_CALENDAR               GREGORIAN                             3
NLS_DATE_FORMAT            YYYY/MM/DD HH24:MI:SS                 3
NLS_DATE_LANGUAGE          JAPANESE                              3
NLS_CHARACTERSET           AL32UTF8                              3
NLS_SORT                   BINARY                                3
NLS_TIME_FORMAT            HH24:MI:SSXFF                         3
NLS_TIMESTAMP_FORMAT       RR-MM-DD HH24:MI:SSXFF                3
NLS_TIME_TZ_FORMAT         HH24:MI:SSXFF TZR                     3
NLS_TIMESTAMP_TZ_FORMAT    RR-MM-DD HH24:MI:SSXFF TZR            3

PARAMETER                 VALUE           CON_ID
_________________________ ____________ _________
NLS_DUAL_CURRENCY         \                    3
NLS_NCHAR_CHARACTERSET    AL16UTF16            3
NLS_COMP                  BINARY               3
NLS_LENGTH_SEMANTICS      BYTE                 3
NLS_NCHAR_CONV_EXCP       FALSE                3

19行が選択されました。
```

# login.sqlの作成
例えば、``%HOMEDRIVE%%HOMEPATH%\login.sql``を作ります。
``SET ENCODING UTF-8``を記述しないと文字化けます。``login.sql``に記述しなくとも、ログインした後に``SQL> ``のプロンプトが出た後で``SET ENCODING UTF-8``すればよいと思うのですが、なぜか``login.sql``に入れておかないとダメでした。

```SQL:login.sql
SET ENCODING UTF-8
SET SQLPROMPT "_USER@_CONNECT_IDENTIFIER> "
alter session set nls_date_format='YYYY/MM/DD HH24:MI:SS';
```

# SQLcl起動用バッチファイルの作成
例えば``c:\opt\bin\SQLclUTF8.bat``を作ります。

```bat:SQLclUTF8.bat
@echo off
chcp 65001
:: tnsnames.oraの場所
SET TNS_ADMIN=%HOMEDRIVE%%HOMEPATH%
:: SQLclの場所
SET AP_PATH=C:\opt\programs\sqldeveloper\sqldeveloper\bin
:: login.sqlの場所
SET SQLPATH=%HOMEDRIVE%%HOMEPATH%

%AP_PATH%\sql %1%
```

# Windows Terminal上でSQLcl起動用バッチファイルを実行するのショートカットを作成
``Windows Terminal``をインストールしている前提で、そのインストールの仕方は省略します。

``Windows Terminal``のショートカットの引数に上記バッチファイルを記述します。

## Windows Terminalのショートカットを作成
+ デスクトップで右クリックメニューを表示し「新規作成(X)」「ショートカット(S)」メニューアイテムをクリックします。
+ ショートカットの作成ダイアログが表示されるので、「項目の場所を入力してください(T):」テキストボックスで、``wt``と入力し「次へ(N)」ボタンをクリックします。
+ 「このショートカットの名前を入力してください(T):」テキストボックスで``SQLcl``を入力し「完了(F)」をクリックします。
+ デスクトップにSQLclショートカットアイコンができているので、右クリックメニューで「プロパティ(R)」メニューアイテムをクリックします。``～\AppData\Local\Microsoft\WindowsApps\wt.exe``に次の引数をつけます。

```
～\AppData\Local\Microsoft\WindowsApps\wt.exe new-tab --colorScheme "Tango Light" "c:\opt\bin\SQLclUTF8.bat" "/nolog"
```
+ 「作業フォルダ(S)」テキストボックスに「``%HOMEDRIVE%%HOMEPATH%``」を入力して、「OK」ボタンをクリックします。

この例では、``colorScheme``にはもともと設定されていた``Tago Light``(背景色白の配色)を使っていますが、配色を自作して名前を付けて保存しておけば、それを利用できます。例えば、本番環境とテスト環境の色分けができます。

# お試し用sql
上記のバッチファイルで起動したプロンプトから実行します。

```SQL:insutf8.sql
SET ENCODING UTF-8

spool "c:\temp\insutf8.log"

conn a001/a001@ORCLPDB1_UTF8
SHOW ENCODING
SHOW SQLFORMAT

drop table t_order_item cascade constraint;

create table t_order_item (
  order_item_id decimal(7,0) not null
  , shipping_address_desc char(50)
  , constraint pk_t_order_item primary key ( order_item_id )
)
;
insert into t_order_item (order_item_id, shipping_address_desc) values(1, '漢字(0x301C:〜)(0xFF5E:～)');
insert into t_order_item (order_item_id, shipping_address_desc) values(2, 'ｶﾀｶﾅ');
insert into t_order_item (order_item_id, shipping_address_desc) values(3, 'ABC@!\~');
insert into t_order_item (order_item_id, shipping_address_desc) values(4, '𩸽(ほっけ)');

commit;

SET SQLFORMAT CSV
SHOW SQLFORMAT
select * from t_order_item;

SET SQLFORMAT INSERT
SHOW SQLFORMAT
select * from t_order_item;

SET SQLFORMAT ANSICONSOLE
SHOW SQLFORMAT
select * from t_order_item;

spool off

```

# 実行結果

SQLcl起動メッセージの文字化けは解消できなかったです。
「𩸽(ほっけ)」がサロゲートペア文字。DOS窓だと``chcp 65001``してもサロゲートペア文字は文字化けますが、
``Windows Terminal``なら大丈夫。
あと、``SQLFORMAT ANSICONSOLE``だと日本語が文字化けます。

```
Active code page: 65001


SQLcl: �y 10�� 08 20:27:56 2022�̃����[�X22.2 Production

Copyright (c) 1982, 2022, Oracle.  All rights reserved.

SP2-0640: 接続されていません
@> cd c:\opt\bin
@> @insutf8.sql
接続しました.

Sessionが変更されました。

encoding "UTF-8"
SQL書式: ansiconsole

Table T_ORDER_ITEMが削除されました。


Table T_ORDER_ITEMは作成されました。


1行挿入しました。


1行挿入しました。


1行挿入しました。


1行挿入しました。


コミットが完了しました。

SQL書式: CSV
"ORDER_ITEM_ID","SHIPPING_ADDRESS_DESC"
1,"漢字(0x301C:〜)(0xFF5E:～)                    "
2,"ｶﾀｶﾅ                                      "
3,"ABC@!\~                                           "
4,"𩸽(ほっけ)                                   "

SQL書式: INSERT
REM INSERTING into T_ORDER_ITEM
SET DEFINE OFF;
Insert into T_ORDER_ITEM (ORDER_ITEM_ID,SHIPPING_ADDRESS_DESC) values (1,'漢字(0x301C:〜)(0xFF5E:～)
');
Insert into T_ORDER_ITEM (ORDER_ITEM_ID,SHIPPING_ADDRESS_DESC) values (2,'ｶﾀｶﾅ                                      ');
Insert into T_ORDER_ITEM (ORDER_ITEM_ID,SHIPPING_ADDRESS_DESC) values (3,'ABC@!\~
    ');
Insert into T_ORDER_ITEM (ORDER_ITEM_ID,SHIPPING_ADDRESS_DESC) values (4,'𩸽(ほっけ)                                   ');

SQL書式: ANSICONSOLE

   ORDER_ITEM_ID SHIPPING_ADDRESS_DESC
________________ _____________________________________________________
               1 ����(0x301C:?)(0xFF5E:�`)
               2 ����
               3 ABC@!\~
               4 ?(�ق���)

A001@ORCLPDB1_UTF8>
```