0

如果我正确理解 NpgsqlCopyIn 和 NpgsqlCopySerializer 应该像这样工作:

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;
}

ArgumentOutOfRangeException在处理两个转义序列 ( \rand \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 回答