4

我一直在使用 C# 为我们的产品为不同的数据库编写具体的提供程序实现。无需详细说明,其中一列是字节数组类型(postgres 中的字节 - 由于偏好字节茶被选择而不是 blob)。唯一的问题是它不会返回插入的相同值。当我插入 Int32 ("0") 时,我得到 8 [92 和 8x 48](而不是 [0,0,0,0])。我需要一个性能明智的解决方案,它将返回我插入的纯字节,而不是 8 字节上值“0”的 ASCII 表示。

我正在使用 Npgsql 来检索数据。如果有人知道 c# 的解决方案,我也很乐意学习它。

编辑: Postgres 9.0、.Net 3.5

简化

命令查询: - 里面只有一个插入语句

select InsertOrUpdateEntry(:nodeId, :timeStamp, :data)

数据参数:

byte [] value = BitConverter.GetBytes((int)someValue);

参数分配如下

command.Parameters.Add(new NpgsqlParameter("data", NpgsqlDbType.Bytea) 
{ Value = value });

选择语句:

select * from Entries

我输入的相同字节数组,我想回来。我将衷心感谢您的帮助。

输入:0 0 0 0
电流输出:92 48 48 48 48 48 48 48 48
预期输出:0 0 0 0

4

2 回答 2

5

在 Npgsql 中有一个NpgsqlDataReader类来检索插入的行,例如:

NpgsqlConnection conn = new NpgsqlConnection(connStr);
conn.Open();

NpgsqlCommand insertCmd =
    new NpgsqlCommand("INSERT INTO binaryData (data) VALUES(:dataParam)", conn);
NpgsqlParameter param = new NpgsqlParameter("dataParam", NpgsqlDbType.Bytea);

byte[] inputBytes = BitConverter.GetBytes((int)0);
Console.Write("Input:");
foreach (byte b in inputBytes)
    Console.Write(" {0}", b);
Console.WriteLine();

param.Value = inputBytes;
insertCmd.Parameters.Add(param);
insertCmd.ExecuteNonQuery();

NpgsqlCommand selectCmd = new NpgsqlCommand("SELECT data FROM binaryData", conn);
NpgsqlDataReader dr = selectCmd.ExecuteReader();
if(dr.Read())
{
    Console.Write("Output:");
    byte[] result = (byte[])dr[0];
    foreach(byte b in result)
        Console.Write(" {0}", b);
    Console.WriteLine();
}

conn.Close();

C# 应用程序的结果:

Input: 0 0 0 0
Output: 0 0 0 0

pgAdmin 的结果:

"\000\000\000\000"

编辑:

我找到了你得到的解释:

92 48 48 48 48 48 48 48 48

我用以前的版本 检查了我的代码Npgsql2.0.10-bin-ms.net3.5sp1.zip并得到了上面的结果(当然 pgAdmin 返回\000\000\000\000),所以我认为你能做的最好的就是使用没有这个错误的另一个版本。

解答:用户使用高于 2.0.10 的 Npgsql 版本

于 2011-08-23T12:12:32.303 回答
3

跑了同样的问题,但设法解决了问题,而无需求助于更换驱动程序。

PHP 文档很好地描述了正在发生的事情,Postgres 正在返回转义数据。对照ASCII 表检查你的输出,当你看到92 48... 它是导致八进制转义序列的文本\0xx,就像 PHP 描述的那样。

Postgres 的二进制数据类型解释了输出转义的八位字节。不用担心,有代码示例

解决方案是告诉 Postgres 如何对字节输出进行转义,可以是escapehex。在这种情况下,通过 psql 向 Postgres 发出以下命令以匹配您的数据:

ALTER DATABASE yourdb SET BYTEA_OUTPUT TO 'escape';
于 2013-06-17T16:23:38.873 回答