摘要:在使用字元串處理函數時,有時會出現非預期結果的場景。在排除使用問題後,應該從encoding和數據本身開始排查。 本文分享自華為雲社區《GaussDB(DWS)字元串處理函數返回錯誤結果集排查》,作者: -CHEN111- 。 在使用字元串處理函數時,有時會出現非預期結果的場景。在排除使用問題 ...
摘要:在使用字元串處理函數時,有時會出現非預期結果的場景。在排除使用問題後,應該從encoding和數據本身開始排查。
本文分享自華為雲社區《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), ' '); --結果為6 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。
查看當前庫編放碼類型
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,為客戶預期結果。