本記事は、postgreSQL、特に書籍「SQL 第2版: ゼロからはじめるデータベース操作」で躓いたエラーについての記事です。
最近、インターン先の研修でSQLを勉強し始めました。
そこで、界隈では評価の高いSQL 第2版: ゼロからはじめるデータベース操作を購入して、書籍通りに進めていたところ、日本語のデータをテーブルに挿入する際にエラーが出て躓きました泣
よって筆者が実際に解決した、エラー解決プロセスについて記録しておきます。
もし、本記事で紹介している方法よりももっと簡単な解決方法があるといった場合や、誤って解説している箇所があればどしどしコメントください!!
問題点
↓のように、テーブル内に日本語を含むデータを挿入したところ、、、
解決策
1. コマンドプロンプトでエンコーディングを設定する
1-1. まずは、Windowsのコマンドプロンプトを開き、UTF-8に設定する
chcp 65001
これにより、コマンドプロンプトのエンコーディングが UTF-8 になります。
最終的には、端末のencodingとpsql内でのencodingを一致させる必要がありますが、この段階では端末のencodingを"UTF-8"への設定を完了しています。
これを設定することで、日本語の入力や表示が正しく行われます。
1-2. psql シェルを開く
cmd で chcp 65001 を実行した後、同じウィンドウでpsql シェルを起動します。
psql -U postgres -d shop #アクセスしたいデータベース名がshopの場合
この際、SQL Shell上ではなく、cmd上で実行することに注意してください。そのため、SQl Shellは利用しません。
1-3. データベースを作成する際は、ロケールとエンコーディング設定を UTF-8 に設定する
日本語データの取り扱いが適切に行われるように、データベースを次のコマンドで作成します。
CREATE DATABASE shop
WITH ENCODING 'UTF8'
LC_COLLATE='ja_JP.UTF-8'
LC_CTYPE='ja_JP.UTF-8'
TEMPLATE=template0;
ENCODING 'UTF8' と LC_COLLATE='ja_JP.UTF-8'、LC_CTYPE='ja_JP.UTF-8' により、日本語を含むマルチバイト文字が適切に扱えるようになります。
1-4. 作業中にエンコーディング設定が正しいか確認する。
↓のコードを実行し、どちらも UTF8 になっていることを確認してください。
SHOW client_encoding;
SHOW server_encoding;
もし、UTF8になっていない場合は、↓のコードを実行してUTF8に設定しなおしてください。
SET client_encoding='UTF8';
1-5. ここまで上手くいくと、、、
データベースshopから、↓をタイプし、テーブルshohinを抽出してみましょう。
select * from shohin;
重要なポイント
・エンコーディングとロケールを一致させることで、日本語を含むマルチバイト文字を適切に扱えるようになります。
・cmdのエンコーディング (chcp 65001) を設定した後に psql を起動することが、文字化けを防ぐための重要な手順です。
2.もし、うまくいかない場合は?
筆者も、なかなかうまくいかず色々試行錯誤しました。筆者が実際にうまくいかなかった例を以下に紹介しておきます。
2-1. 日本語を含むデータをテーブルに挿入時にすでにエラーが出る場合➡1-3へ
shohinテーブルに↓を挿入すると、、、
shop=# begin transaction;
BEGIN
shop=*# INSERT INTO Shohin VALUES ('0001', 'Tシャツ', '衣服', 1000, 500, '2009-09-20');
↓のようなエラーが実際に表示されました。
ERROR: é╪?è╪a?-a?Ya,-aƒ¼å?a?_ä,?æ,?æ?å^ç',"shohin_pkey"é?å??a?"a?ªa,Sa?_a?T
この場合、データベース自体のロケール設定自体に問題がある可能性があります。
よって一度↓を実行して、データベースのロケール確認してみましょう。
\l
これは現在のロケールが Japanese_Japan.932 になっています。この「932」というコードは、Windowsの Shift_JIS エンコーディングを指しています。
よってエンコーディングが UTF-8 であっても、ロケールが Shift_JIS に設定されているため、データの扱いに問題が発生する可能性があります。
従って、1-3へ戻り、ロケールを UTF-8 に設定しましょう。
個人的な疑問点
1.今うまく日本語表記できているテーブルは、このcmdを閉じてもリセットされずに保存されるのか?
➡結論、されるそうです。↓chatgpt4-oの回答です。
データベースに保存されたデータは、cmd を閉じても永久的に PostgreSQL サーバー内に保存されます。INSERT 文でデータを挿入し、COMMIT した場合、そのデータはデータベースの一部として保存されるため、cmd を閉じたり、システムを再起動してもデータは残ります。
2.一回cmdを閉じて、またcmdを開けるときさっきの1-1~4の操作をまたしなければいけないのですか?もしそうであればもっと効率的な方法はないの?
➡結論、1-1のchcp 65001
とSET server_encoding='UTF8'
は保存されないそうです。しかし、データベースのロケールの設定は保存されています。この保存されない部分、毎回cmdを開くたびに設定するのはとても面倒、、、どのように効率的にすればいいのでしょうか??(有識者の方々、教えてください泣き)