遭遇した問題
PostgreSQLを使って従業員のデータを管理するテーブルを作成しようと以下のSQLを実行しました
CREATE TABLE employee (
id SERIAL PRIMARY KEY,
family_name VARCHAR(20) NOT NULL,
first_name VARCHAR(20) NOT NULL,
name_kana VARCHAR(20) NOT NULL,
);
INSERT INTO
employee (
id,
family_name,
first_name,
name_kana,
)
VALUES
(
1,
'佐藤',
'一子',
'サトウ イチコ',
) ON CONFLICT (id) DO NOTHING;
しかし、あるエラーにより処理に失敗している…
ERROR: value too long for type character varying(20)
このエラーを見た私は
VARCHAR(20)の最大文字数エラーかぁ😏
エラーが出ているのは文字数的に'サトウ イチコ'だろうな
VARCHAR(50)ぐらいにするか、データ型をTEXTすれば治るだろう…
とたいした調査をせずにそう決めつけて解決しようとしてました
(日本語文字数すら数えず直そうとしてました。よくないですね)
ちょっと待った!
この問題を上司に報告したところ、
「PostgreのVACHAR(n)はバイト数ではなく単純に文字数でカウントされるはずなのでいけるはずだけど?🤔」
とアドバイスをいただきました
PostgreSQLのVARCHAR(n)
ということでPostgreSQLの最大文字数カウントのルールを調査しました
SQL では、
character varying(n)
とcharacter(n)
という2 つの主要な文字型が定義されています。n
は正の整数です。これらの型は両方とも、最大 文字数 (バイト数ではありません) の文字列を格納できます。
たしかにバイト数ではなく文字数でカウントされるらしい
ちなみにcharacter varying(n)
はvarcahr(n)
の別名とのこと。
じゃあなぜエラーになっていたのか?
結論から言うと、DBのエンコードがSQL_ASCIIに設定されていたことが原因でした😅
SQL_ASCIIに設定している場合は、文字エンコードが無視されて日本語データもバイト数で扱うようです
設定がSQL_ASCIIの場合は、符号化は実行されません。よって、この設定は特定の符号化を使用している場合には、その符号化を無視するようになってしまいます。
バイト数でカウントされるなら、
全角文字(サトウイチコ): 6文字 × 3バイト = 18バイト
全角スペース: 1文字 × 3バイト = 3バイト
合計: 21バイト
でエラーになるのは頷けますね
対応策
エンコードをUTF-8に変更すれば解決OK
日本語文字列に対応しているエンコードを設定することで、最大数のカウントをバイトから文字数にすることができます
ちなみに一度作成したDBのエンコード設定は変えられないそうです…
新しくDBを作り直してSQLを実行したら無事通りました😮💨