Webから取ってきた文字列をデータベースへ保存しています。
こうしておくと、あとで集計するとき便利なんです。
さてさて、今回はPostgreSQLデータベースにエラーが出て文字列が入らなかったので、共有いたします。
ERROR: 22021: invalid byte sequence for encoding “UTF8”
C#ではNpgSqlというライブラリを使うと PostgreSQLに対して読み書き可能です。
id SERIAL | message text |
---|---|
のようなテーブルがあったとします。
PostgreSQL のSERIALというのは、MySQLでいうとオートインクリメント列。
何も指定せず挿入すると1ずつ増えていってくれる列です。
そこに、外部から取得した文字列を入れていくコードを書きました。
string message = 外部から取得();
string columnName = “message”;
string q = $”INSERT INTO {tableName} ({columnName}) VALUES (:message)”;
var command = new NpgsqlCommand(q, connection);
command.Parameters.AddWithValue(“message”, message);
command.ExecuteNonQuery();
すると以下のような例外が・・・
ERROR: 22021: invalid byte sequence for encoding “UTF8”
Error: 07P01: invalid message format
続いて、同じことをパラメーターなしでもやってみました。
次はSQLの文字列を直接渡してみました。
string q = $”INSERT INTO {tableName} ({columnName}) VALUES ({message.Replace(“‘”,”””})”;
var command = new NpgsqlCommand(q, connection);
command.ExecuteNonQuery();
こちらでは、以下のような違う例外が発生しました。
Error: 07P01: invalid message format
エラーの原因は?
結論から書くと、message に \0 が入っていました。
message = message.Replace(“\0”, “”);
とすることで解決しました!
あまり、C#でヌル文字を意識しないし、そもそも Unicode文字列の途中に、ヌル文字なんて入るのか?と思ったのですが、どうやら入るみたいです。
https://stackoverflow.com/questions/33060368/can-utf-8-string-contain-nulls-0x0-in-it
それで、PostgreSQLサーバーはそれに対応していないようです。
秀丸エディタなんかに突っ込むと、メッセージを出して消してくれます。
外部から取ってきた文字列・・・ここではHttpから取ってきたものだったのですが、気を付けなければいけませんね。
終わりに
いかがだったでしょうか?
PostgreSQLで、invalid byte sequence for encoding “UTF8” や invalid message format のエラーが出たら文字列の中にヌル文字がないか確認してみましょう。
みなさまのお役に立てればと思います、ではでは!