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

发布于 2024-12-01 02:43:48 字数 859 浏览 2 评论 0原文

我一直在使用 C# 为我们的产品针对不同数据库编写具体的提供程序实现。无需深入了解细节,其中一列是字节数组类型(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

I have been using C# to write a concrete provider implementation for our product for different databases. W/out getting into details, one of the columns is of byte array type (bytea in postgres - due to the preferences bytea was chosen over blob). The only problem, is that it does not return same value that was inserted. When I insert Int32 ("0") I get 8 [92 and 8x 48] (instead of [0,0,0,0]). I need a performance wise solution, that will return pure bytes I have inserted, instead of ASCII representation of value "0" on 8 bytes.

I am using Npgsql to retrive data. If someone knows solution for c# I will be happy to learn it as well.

Edit:
Postgres 9.0, .Net 3.5

Simplification

Command query: - inside it only does an insert statment

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

Data parameter:

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

Parameter is assigned as below

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

Select statments:

select * from Entries

Same byte array I have entered, I want to get back. I would really appreciate your help.

Input: 0 0 0 0
Current Output: 92 48 48 48 48 48 48 48 48
Expected Output: 0 0 0 0

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

暗藏城府 2024-12-08 02:43:49

遇到了同样的问题,但无需更换驱动程序即可解决问题。

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

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

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

ALTER DATABASE yourdb SET BYTEA_OUTPUT TO 'escape';

Ran the same problem, but managed to solve the problem without having to resort to changing drivers.

PHP documentation has a good description of what's happening, Postgres is returning escaped data. Check your output against an ASCII table, when you see 92 48 ... it's the text lead in to an octal escape sequence, \0xx, just like PHP describes.

Postgres's binary data type explains the output escaped octets. Fret not, there are code examples.

The solution is to tell Postgres how to bytea output is escaped, which can be either escape or hex. In this case issue the following to Postgres via psql to match your data:

ALTER DATABASE yourdb SET BYTEA_OUTPUT TO 'escape';
标点 2024-12-08 02:43:48

在 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 版本

In Npgsql there is NpgsqlDataReader class to retrieve inserted rows, e.g:

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();

Result from C# app:

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

Result from pgAdmin:

"\000\000\000\000"

EDIT:

I found explanation why you getting:

92 48 48 48 48 48 48 48 48

I checked my code with previous version Npgsql2.0.10-bin-ms.net3.5sp1.zip and get above result (of course pgAdmin returns \000\000\000\000), so I think that best what you can do is to use another version without this bug.

ANSWER: User higher version of Npgsql than 2.0.10

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文