写点什么

GaussDB(DWS) 字符串处理函数返回错误结果集排查

  • 2023-05-06
    广东
  • 本文字数:935 字

    阅读完需:约 3 分钟

GaussDB(DWS)字符串处理函数返回错误结果集排查

本文分享自华为云社区《GaussDB(DWS)字符串处理函数返回错误结果集排查》,作者: -CHEN111- 。


在使用字符串处理函数时,有时会出现非预期结果的场景。在排除使用问题后,应该从 encoding 和数据本身开始排查。


直接从案例出发。

(一)案例背景


客户执行 instr 查空格下标,子查询中查询结果与将子查询的结果粘出来单独执行结果集不一致。


SELECT instr((SELECT a FROM t1), ' ') xxxxx; SELECT a FROM t1; 的结果是a -> SELECT instr(a, ' ');
复制代码


假设当前select a from t1;通过数据库连接客户端查询后显示结果集为“测试测 试 测试”


SELECT instr((SELECT a FROM t1), ' '); --结果为6SELECT instr('测试测 试 测试', ' '); --结果为4
复制代码

(二)问题排查


从上述结果集中可以看出,如果把SELECT a FROM t1;的结果集单独复制出来,则其结果 4 为预期结果,而当SELECT a FROM t1;作为子查询进行 instr 处理时,结果为 6 是不符合预期的。排查主要从 encoding 和子查询结果集入手

1. 先判断 encoding


不同的编码类型下,字符串处理也不相同。


  • UTF8 是按字符算个数

  • SQL_ASCII 是按字节算个数


对于“测试测 试 测试”而言,按字符个数计算,SELECT instr('测试测 试 测试', ' ')的结果应为 4;按字节个数计算,一个汉字占 3 个字节,SELECT instr('测试测 试 测试', ' ')的结果应为 10。


查看当前库编放码类型


SHOW server_encoding;
复制代码


结果为 UTF8,故预期结果应该为 4,但是SELECT instr((SELECT a FROM t1), ' ');结果却为 6。

此时开始怀疑是否是客户端查询导致字符串结果集显示错误

2. 子查询结果集排查


通过编解码拿到字符串结果集的十六进制


SELECT encode(a, 'hex') AS res FROM t1;                   res------------------------------------------ e6b58be8af95e6b58b0d0ae8af9520e6b58be8af95(1 row)
复制代码


在本地解码后结果集为


SELECT  convert_from(decode('e6b58be8af95e6b58b0d0ae8af9520e6b58be8af95','hex'),'utf8'); convert_from-------------- 测试测\r    + 试 测试
复制代码


可以看出,字符串结果集中,‘测试测’后并非空格,而是’\r +’。

3. 解决方案


将’\r +'按照编解码的形式替换空格


SELECT instr((SELECT a FROM t1), convert_from(decode('0d0a','hex'),'utf8'));
复制代码


此时结果为 4,为客户预期结果。


点击关注,第一时间了解华为云新鲜技术~

发布于: 刚刚阅读数: 4
用户头像

提供全面深入的云计算技术干货 2020-07-14 加入

生于云,长于云,让开发者成为决定性力量

评论

发布
暂无评论
GaussDB(DWS)字符串处理函数返回错误结果集排查_云计算_华为云开发者联盟_InfoQ写作社区