Postgres bytea列返回字符串(char数组)而不是字节数组

时间:2011-08-22 17:00:59

标签: c# postgresql bytearray binary-data npgsql

我一直在使用C#为不同数据库的产品编写具体的提供程序实现。 W / out进入细节,其中一列是字节数组类型(postgres中的bytea - 由于首选项bytea是在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

2 个答案:

答案 0 :(得分: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#app的结果:

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),所以我认为最好的办法就是使用没有这个bug的另一个版本。

答案: Npgsql的用户更高版本比2.0.10

答案 1 :(得分:3)

遇到同样的问题,但设法解决问题而不必诉诸更改驱动程序。

PHP documentation很好地描述了发生了什么,Postgres正在返回转义数据。当您看到92 48时,检查输出是否为ASCII table ...它是文本引导到八进制转义序列\0xx,就像PHP描述的那样。

Postgres的binary data type解释了输出转义的八位字节。不用担心,有code examples

解决方案是告诉Postgres如何转义bytea输出,可以是escapehex。在这种情况下,通过psql向Postgres发出以下内容以匹配您的数据:

ALTER DATABASE yourdb SET BYTEA_OUTPUT TO 'escape';