NpgSql-使用解码函数从查询返回的错误数据

本文关键字:查询 返回 错误数据 函数 解码 NpgSql- | 更新日期: 2023-09-27 18:25:34

我目前正在开始将应用程序的postgres 8.4 db升级到9.4。实际的DB迁移进行得很完美,但在9.4 DB上运行时,一些应用程序查询没有返回奇怪的结果。我正在使用NpgSql v2.0.12.0库作为C#。这个问题似乎与几个表有关,这些表存储编码为base64字符串的文本数据。查询调用postgres解码函数,以便以纯文本形式返回编码数据。例如:

  SELECT
     decode(user_name, 'base64')::text as user_name
   FROM
     login
   WHERE
     login_id = 123;

当提交到8.4 DB时,字符串将正确返回到应用程序。当提交到9.4 DB时,我得到

'x61646d696e6973747261746f72

在PgAdmin SQL工具中,这两种情况下的结果都是正确的。我确信这可能是某种编码问题,但就我而言,我无法弄清楚——我在谷歌上搜索了几个小时,翻阅了postgres文档,并在这里无休止地搜索,最终未能找到解决我问题的方法。希望有一些PostGres的家伙能为我指明正确的方向来解决这个问题。

NpgSql-使用解码函数从查询返回的错误数据

在当前编码中,您一直依赖于将bytea输出解释为字符串,即您的代码一直存在缺陷,但碰巧可以工作。

较旧的PostgreSQL版本对字节文字使用"转义"格式,这看起来像7位ASCII字符的纯文本,对不可打印和8位字符使用八进制转义,例如

test=> SET bytea_output = 'escape';
SET
test=> SELECT convert_to('administrator á
', 'utf-8');
         convert_to         
----------------------------
 administrator '303'241'012
(1 row)

后来的PostgreSQL版本默认为"十六进制"输出,将所有编码为十六进制:

test=> SET bytea_output = 'hex';
SET
test=> SELECT convert_to('administrator á
', 'utf-8');
              convert_to              
--------------------------------------
 'x61646d696e6973747261746f7220c3a10a
(1 row)

所以你的应用程序不能再假设字节是文本了。

如果base64字符串是当前本地文本编码中的有效文本,则可以使用convert_from(decode(user_name, 'base64'), 'utf-8')。但在这种情况下,您应该将其存储为普通的text,而不是最初编码的base64。

如果base64字符串在当前编码中无效,例如它包含空字节、无法在client_encoding中表示的字符等,则应返回十六进制或base64表示,并在客户端应用程序中对其进行解码。