文档首页/ 数据仓库服务 GaussDB(DWS)/ 故障排除/ 数据库使用/ 执行业务报错could not determine which collation to use for string hashing
更新时间:2024-07-01 GMT+08:00

执行业务报错could not determine which collation to use for string hashing

问题现象

执行SELECT查询时报错could not determine which collation to use for string hashing。

1
2
3
4
5
6
CREATE TABLE t(a text collate "C", b text collate case_insensitive);
INSERT INTO t VALUES('Hello','world');
——计算ifnull(a,b)的值的哈希值
SELECT hashtext(ifnull(a,b)) FROM t;
ERROR:  dn_6005_6006: could not determine which collation to use for string hashing.
HINT:  Use the COLLATE clause to set the collation explicitly.

hashtext函数用于计算适当数据类型的值的哈希值。此处仅用作示例说明出现collate冲突时应该如何解决。

原因分析

表t中有两个字段,且两个字段的排序规则不同,字段a的排序规则为C(安装数据库时的默认排序规则),字段b的排序规则为case_insensitive(不区分大小写),SELECT语句中表达式hashtext(ifnull(a,b))存在多个collation造成冲突,执行报错。

处理方法

当字符串表达式中collation有多个时,可手动指定COLLATE collation_name。

执行SELECT时,指定表达式ifnull(a,b)的排序规则为C或者case_insensitive。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
SELECT hashtext(ifnull(a,b) collate "C") FROM t;
 hashtext
-----------
 820977155
(1 row)

SELECT hashtext(ifnull(a,b) collate case_insensitive) FROM t;
 hashtext
-----------
 238052143
(1 row)

扩展

除上述场景会出现存在多个collation造成冲突,以下两种场景也会出现多个collation,报错不同但解决方法相同。

  • 场景一

    SELECT语句中比较表达式a=b存在多个collation造成冲突,执行报错could not determine which collation to use for string comparison。

    1
    2
    3
    SELECT a=b FROM t;
    ERROR:  dn_6001_6002: could not determine which collation to use for string comparison
    HINT:  Use the COLLATE clause to set the collation explicitly.
    

    执行SELECT时,指定表达式a=b的排序规则为case_insensitive。

    1
    2
    3
    4
    5
     SELECT a=b COLLATE case_insensitive FROM t;
     ?column?
    ----------
     f
    (1 row)
    
  • 场景二

    SELECT语句中表达式instr(a,b)存在多个collation造成冲突,执行报错could not determine which collation to use for string searching。

    1
    2
    3
    SELECT instr(a,b) FROM t;
    ERROR:  dn_6005_6006: could not determine which collation to use for string searching
    HINT:  Use the COLLATE clause to set the collation explicitly.
    

    执行SELECT时,指定字段a的排序规则为case_insensitive或者指定字段b的排序规则为C来保证字段排序规则的统一。

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    SELECT instr(a collate case_insensitive,b) FROM t;
     instr
    -------
         0
    (1 row)
    
    SELECT instr(a,b collate "C") FROM t;
     instr
    -------
         0
    (1 row)