为PostgreSQL数据库过滤C#中UTF8编码的无效字节序列

时间:2014-06-25 15:16:10

标签: c# postgresql utf-8 odbc npgsql

我一直在寻找并尝试很多不同的解决方案来解决这个问题,但还没有找到答案。基本上,我使用COPY查询将数据从ODBC连接插入PostgreSql数据库,但COPY查询停止并返回此错误...

ERROR:  invalid byte sequence for encoding "UTF8": 0x92
CONTEXT:  COPY [TableName], line 1: "189572|1-00-1202|1-|00-|1202||AP||1...
STATEMENT:  COPY [TableName] FROM STDIN (DELIMITER '|', NULL '')

ODBC连接驱动程序设置为ANSI,它从中提取的Sybase / Advantage数据库编码为Unicode。要将此错误消息放在透视图中,在360,000个条目中,它只会在其中一个条目上跳闸。问题是COPY查询停止,即使出现一个错误也无法完成。

以下是我提取数据的C#代码......

OdbcDataReader reader = test.ExecuteReader();
int rowCount = reader.FieldCount;

while (reader.Read())
{

    for (int i = 0; i < rowCount; i++)
    {
        dataEntry = dataEntry + reader[i].ToString() + "|";
    }

    dataEntry = dataEntry.Trim().Substring(0, dataEntry.Length - 1).Replace("\r",string.Empty).Replace("\n", string.Empty);

    UTF8Encoding utf8 = new UTF8Encoding();

    var raw = utf8.GetBytes(string.Concat(dataEntry,"\n"));

    copy.CopyStream.Write(raw, 0, raw.Length);
    dataEntry = "";
}

基本上,我正在寻找一种方法来过滤C#中无效的UTF8字节序列,并将其删除或用不同的字符替换它们,以便COPY查询不会报告错误。任何帮助是极大的赞赏。谢谢。

1 个答案:

答案 0 :(得分:1)

0x92是Unicode U+0092 private use 2

PostgreSQL支持这个角色:

regress=> SELECT E'\u0092', length(E'\u0092');
 ?column? | length 
----------+--------
 \u0092   |      1
(1 row)

所以你不应该收到错误。在PostgreSQL实例上运行上述语句并报告结果。

然而,这可能是一种症状。很可能char是转义序列的第二部分而你的代码没有做正确的解码,所以第一部分被用作一些不相关的字符而不是转义,然后你在这里遇到错误。

这让我想知道:

  

ODBC连接驱动程序设置为ANSI,它从中提取的Sybase / Advantage数据库编码为Unicode

...为什么不在Unicode模式下使用Sybase驱动程序?

如果您在ANSI模式下使用它,则必须确保您(或C#驱动程序接口)正确解码Sybase从发送的原始编码字符串发送的数据。

我没有看到在这里过滤掉不良数据的方法,因为您的C#应用​​程序正在生成utf-8。它应该是有效的utf-8。如果你正在谈论由于某些原因而无法应对U + 0092的旧/错误版本的Pg,在转换为utf-之前,你总是可以像对待其他替换一样过滤掉那个角色。 8。