昨年7月20日 / 今年1月12日の2記事であきらめてた件。ページャlessのWindows版の存在を知って試したら一部解決で、UTF-8のクエリ結果を受け取って表示することはできました。
ただUTF-8のコマンドプロンプトで日本語フォントを使うのは容易でないし、ASCII以外の文字を含むクエリを送るとpsqlが強制終了してしまう問題はそのまま。抜本策ではありませんが、とりあえずlessのセットアップと、psqlでの基本的な使い方を書きます。Windows7 x64 + PostgreSQL 9.5.3付属のpsqlで動作確認しました。
Contents
- コードページ65001(UTF-8)で起きるnot enough memory問題
- Windows版lessのセットアップ
- psqlでの使い方
コードページ65001(UTF-8)で起きるnot enough memory問題
詳細は昨年7月20日に書きましたが、おさらいすると ↓
1)Shift JISにない文字、例えばユーロ「€」をクエリで受け取りたい。日本語版Windowsのコマンドプロンプトは「コードページ932」≒Shift JISなので、そのままではエラー。↓
# select chr(x'20ac' :: int) ; -- ユーロ記号を16進コードポイントでクエリ
ERROR: 符号化方式"UTF8"における0xe2 0x82 0xacバイトシーケンスを持つ文字は
"SJIS"符号化方式では等しくありません
2)コマンドプロンプトは置いといて、psqlの「クライアントエンコーディング」をUTF-8に変えても駄目(文字化けする)↓
# \encoding utf8
# select chr(x'20ac' :: int);
chr
-----
竄ャ
(1 行)
3)そこでコマンドプロンプトを「コードページ65001」≒UTF-8にすると、文字コードに関係なく全てのクエリが not enough memoryエラーで不能 ↓ 何でだよー!! またクエリにASCII以外があるとpsqlが強制終了してしまう…
# \! chcp 65001
(自動的に画面クリアされ、フォントも変わる)
Active code page: 65001
# select chr(x'20ac' :: int);
Not enough memory.
# select 1;
Not enough memory.
4)Not enough memoryエラーはpsqlでなくページャ(more.com)が起こしてるので、ページャ不使用に設定すると ↓ASCIIが返るクエリは正常に表示。でもやっぱりUTF-8は文字化けするし、フォントが日本語以外になってるので困ります。
# \pset pager off
Pager usage is off.
# select 1;
?column?
----------
1
(1 row)
# select chr(x'20ac' :: int);
chr
-----
竄ャ
(1 row)
…と八方ふさがりでしたが、Windows以外での標準的ページャ「less」がWindowsにも移植されてると知り、more.comをそれに置き換えればNot enough memoryエラーは消え、UTF-8を含むクエリ結果も正常に表示されました。
Windows版lessのセットアップ
lessの公式サイト → ダウンロードページ → Windows版のファイル置き場(Index of /misc/less)とたどり、less-481-win32-x86.7zをダウンロードしました。中身は ↓ で、ファイルのうちless.exeを単体で使えば今回の件は足ります。
↓ 適当な所に解凍し、起動するかless --helpで確認。文字・背景色も変えられるので、エスケープシーケンスが効くみたいです。この件は後日調べる予定。
psqlでの使い方
起動する前に、コマンドプロンプトのコードページを ↓ のようにUTF-8に変更。勝手にフォント・文字サイズ・ウィンドウサイズが変わって画面もクリアされます。もし忘れたら、psql起動後でもメタコマンド\! chcp 65001で可能。
> chcp 65001
(画面クリアされ、フォント、文字サイズ、ウィンドウサイズが変わる)
Active code page: 65001
psqlを起動すると、英語でWarningが出ます。これは親切な「お知らせ」で、コマンドプロンプトとシステムでコードページが違うというもの。今回は出て当然です。
> psql -U postgres
psql (9.5.3)
WARNING: Console code page (65001) differs from Windows code page (932)
8-bit characters might not work correctly. See psql reference
page "Notes for Windows users" for details.
Type "help" for help.
postgres=#
後はクライアントエンコーディングをUTF-8に、ページャをlessに設定します。クエリはASCIIのみという制約つきですが(でないとpsqlが強制終了)、結果は嘘みたいに普通に表示されました。下記でのlessオプション(-X)は一例で、コマンドの直後に結果を挿入して表示するもの。
# \encoding utf8
# \setenv pager 'r:/less -X'
# select chr(x'20ac' :: int); -- ユーロ記号を、16進コードポイントでクエリ
chr
-----
€
(1 row)
注意点として、メタコマンド\pset pagerを使うのでなく(これはページャのON・OFF切り替え)、環境変数pagerを\setenvコマンドで設定すること。またpsqlを終了すると設定が消えるので、次回起動時も同様の設定が必要です。
これでUTF-8を含むクエリ結果を表示できるようになったけど、クエリがASCIIしか使えないのは大変な制約。今回の「コマンドプロンプト=クライアントエンコーディング= UTF-8」という環境の実用性は薄いです。結局、UTF-8対応としてはCygwin版psqlしかない状態で、いずれ別記事に書きます。