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

我一直在使用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

在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更高

遇到同样的问题,但设法解决问题,而不必诉诸改变司机。

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

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

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

 ALTER DATABASE yourdb SET BYTEA_OUTPUT TO 'escape'; 
Interesting Posts