0

私が正しく理解していれば、NpgsqlCopySerializer を使用した NpgsqlCopyIn は次のように動作するはずです。

var conn = new NpgsqlConnection(ConfigurationManager.ConnectionStrings["PostgreSqlDb"].ConnectionString);
conn.Open();
var tran = conn.BeginTransaction();
var cmd = new NpgsqlCommand("COPY address (id, employee, value) FROM STDIN", conn);
var npgsqlCopySerializer = new NpgsqlCopySerializer(conn);
var npgsqlCopyIn = new NpgsqlCopyIn(cmd, conn, npgsqlCopySerializer.ToStream);

try
{
    npgsqlCopyIn.Start();
    npgsqlCopySerializer.AddInt32(300);
    npgsqlCopySerializer.AddInt32(1);
    npgsqlCopySerializer.AddString("address");
    npgsqlCopySerializer.EndRow();
    npgsqlCopySerializer.Flush();
    npgsqlCopySerializer.AddInt32(301);
    npgsqlCopySerializer.AddInt32(1);
    npgsqlCopySerializer.AddString("another\r\naddress");
    npgsqlCopySerializer.EndRow();
    npgsqlCopySerializer.Flush();
    npgsqlCopyIn.End();

    tran.Commit();
}
//catch (Exception e)
//{
//    tran.Rollback();
//    throw;
//}
finally
{
    conn.Close();
}

問題は、許可されていない文字が含まれるたびに、そのメソッド内AddString()でスローされることArgumentOutOfRangeExceptionです。それ以外の場合は機能します。

例えば:

npgsqlCopySerializer.AddString("another\r\naddress");

テキスト形式(行区切り)からのコピーで特別な意味を持ち、エスケープする必要がある改行が含まれているため、例外がスローされます。

それを機能させるために私に何ができるか知っている人はいますか?インターネットで例を検索しましたが、何も見つかりませんでした。

ご協力いただきありがとうございます!

4

2 に答える 2

2

ドキュメントから引用するには:

COPYデータを生成するアプリケーションは、データの改行とキャリッジリターンをそれぞれ\nシーケンスと\rシーケンスに変換することを強くお勧めします。現在、データキャリッジリターンをバックスラッシュとキャリッジリターンで表し、データ改行をバックスラッシュとニューラインで表すことができます。

したがって、次のように機能すると思います。

npgsqlCopySerializer.AddString("another\\\r\\\naddress");

編集:私は自分でそれを試しましたが、バグがあるようですNpgsqlCopySerializer.AddString()

if (escapeAt > bufferedUpto)
{
    int encodedLength = ENCODING_UTF8.GetByteCount(fieldValue.ToCharArray(bufferedUpto, escapeAt));
    MakeRoomForBytes(encodedLength);
    _sendBufferAt += ENCODING_UTF8.GetBytes(fieldValue, bufferedUpto, escapeAt, _sendBuffer, _sendBufferAt);
    bufferedUpto = escapeAt;
}

ArgumentOutOfRangeException2行目は、2つのエスケープシーケンス(\rおよび\n)が処理されて出力バッファに追加された後にスローしbufferedUpto == 9ます。escapeAt == "another\r\naddress".Length == 16

今では、このバグがNpgsqlトラッカーで報告されていることもわかりました。

于 2012-08-06T09:15:18.290 に答える
2

偶然にも数日前にバグを報告したのは私です。

挿入しようとしている XML を投稿していただけませんか? OSM の結果で試してみました: http://nominatim.openstreetmap.org/search.php?q=A7&viewbox=3.96%2C52.82%2C7.93%2C51.11&format=xml

そして、かなり大きな web.config ファイルで、どちらも問題なく動作します。修正プログラムの送信中にコピー/貼り付けエラーが発生したか、挿入しようとしている XML が試した XML とは異なります。

また、以前とまったく同じエラー (つまり、引数が範囲外) が発生しますか? デフォルトのバッファ サイズはわずか 8k で、私の場合は十分ではありませんでした。

違いがあるかどうかはわかりませんが、フラッシュはまったく使用しませんでした。

NpgsqlConnection Conn = new NpgsqlConnection(getPostgresConnString());
Conn.Open();
NpgsqlCopyIn copyIn = new NpgsqlCopyIn("COPY table  (col1,col2,col2)   FROM STDIN;", Conn);
copyIn.Start();
NpgsqlCopySerializer cs1 = new NpgsqlCopySerializer(pConn2);
cs1.AddString(System.IO.File.ReadAllText("C:\\test\\Web.config"));
[...]
cs1.EndRow();
cs1.Close();
copyIn.End();
于 2012-08-07T07:20:35.843 に答える