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输出,可以是escape
或hex
。 在这种情况下,通过psql向Postgres发出以下内容以匹配您的数据:
ALTER DATABASE yourdb SET BYTEA_OUTPUT TO 'escape';