翼度科技»论坛 编程开发 mysql 查看内容

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

3

主题

3

帖子

9

积分

新手上路

Rank: 1

积分
9
摘要:在使用字符串处理函数时,有时会出现非预期结果的场景。在排除使用问题后,应该从encoding和数据本身开始排查。
本文分享自华为云社区《GaussDB(DWS)字符串处理函数返回错误结果集排查》,作者: -CHEN111- 。
在使用字符串处理函数时,有时会出现非预期结果的场景。在排除使用问题后,应该从encoding和数据本身开始排查。
直接从案例出发。
(一)案例背景

客户执行instr查空格下标,子查询中查询结果与将子查询的结果粘出来单独执行结果集不一致。
  1. SELECT instr((SELECT a FROM t1), ' ') xxxxx;
  2. SELECT a FROM t1; 的结果是a -> SELECT instr(a, ' ');
复制代码
假设当前select a from t1;通过数据库连接客户端查询后显示结果集为“测试测 试 测试”
  1. SELECT instr((SELECT a FROM t1), ' '); --结果为6
  2. SELECT 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。
查看当前库编放码类型
  1. SHOW server_encoding;
复制代码
结果为UTF8,故预期结果应该为4,但是SELECT instr((SELECT a FROM t1), ' ');结果却为6。
此时开始怀疑是否是客户端查询导致字符串结果集显示错误
2. 子查询结果集排查

通过编解码拿到字符串结果集的十六进制
  1. SELECT encode(a, 'hex') AS res FROM t1;
  2.                    res
  3. ------------------------------------------
  4. e6b58be8af95e6b58b0d0ae8af9520e6b58be8af95
  5. (1 row)
复制代码
在本地解码后结果集为
  1. SELECT  convert_from(decode('e6b58be8af95e6b58b0d0ae8af9520e6b58be8af95','hex'),'utf8');
  2. convert_from
  3. --------------
  4. 测试测\r    +
  5. 试 测试
复制代码
可以看出,字符串结果集中,‘测试测’后并非空格,而是’\r +’。
3. 解决方案

将’\r +'按照编解码的形式替换空格
  1. SELECT instr((SELECT a FROM t1), convert_from(decode('0d0a','hex'),'utf8'));
复制代码
此时结果为4,为客户预期结果。
 
点击关注,第一时间了解华为云新鲜技术~

来源:https://www.cnblogs.com/huaweiyun/p/17377489.html
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作!

举报 回复 使用道具