プログラミング

    [PostgreSQL] Error: 07P01: invalid message format

    Webから取ってきた文字列をデータベースへ保存しています。
    こうしておくと、あとで集計するとき便利なんです。

    さてさて、今回はPostgreSQLデータベースにエラーが出て文字列が入らなかったので、共有いたします。

    ERROR: 22021: invalid byte sequence for encoding “UTF8”

    C#ではNpgSqlというライブラリを使うと PostgreSQLに対して読み書き可能です。

    id SERIALmessage 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 のエラーが出たら文字列の中にヌル文字がないか確認してみましょう。

    みなさまのお役に立てればと思います、ではでは!