使用encode(bytea)结合like/ilike处理Unicode时失效的原因
问题原因解释
核心问题:escape编码的转义字符与LIKE/ILIKE的转义逻辑冲突
- 当
bytea包含非ASCII字节(比如你例子中的UTF-8多字节Unicode字符)时,encode(cid, 'escape')会将这些字节转换为反斜杠+八进制数字的转义格式(例如\xd0被编码为\320,\xa2被编码为\242)。 - PostgreSQL的
LIKE/ILIKE操作符默认将反斜杠(\)视为转义字符,而非普通字符串的一部分。这意味着匹配时,LIKE会尝试用反斜杠转义后续字符,而不是直接匹配反斜杠本身。 - 以你的第二个测试为例:
encode后的字符串包含\320这类序列,LIKE会把\当成转义符,试图解析后续的3作为转义后的目标,而非将\320作为完整的字符串片段匹配,最终导致匹配失败。 - 而
=操作符是逐字符直接比较,不会处理任何转义逻辑,因此即便字符串包含反斜杠,=也能正确判断相等,这就是b列返回true但c/d列返回false的原因。
验证示例
你可以通过以下SQL验证转义逻辑的影响:
-- 默认LIKE匹配含反斜杠的字符串,返回false SELECT '\320' LIKE '\320'; -- 使用转义字符串(E'')处理反斜杠,返回true SELECT '\320' LIKE E'\\320'; -- 禁用转义符,返回true SELECT '\320' LIKE '\320' ESCAPE '';
内容的提问来源于stack exchange,提问作者mr mcwolf
相关产品推荐
相关产品推荐

