HEX()将字符串或整数转为十六进制字符串(如'A'→'41',255→'FF'),UNHEX()严格逆向还原,仅接受偶数长度、纯0-9/A-F/a-f字符串,非法输入静默返回NULL。

HEX() 和 UNHEX() 不是通用函数,MySQL 支持,PostgreSQL/SQL Server/SQLite 原生不支持 —— 直接用会报 Unknown function 'HEX' 或类似错误。
MySQL 中 HEX() 把字符串转成十六进制字符串
它把输入的每个字节转为两位十六进制字符(大写),结果是 VARCHAR 类型。注意:不是 Base64,也不是编码转换,纯字节到 hex 的映射。
- 对中文、emoji 等多字节字符,按实际 UTF8 编码字节展开:
HEX('中')返回'E4B8AD'(UTF8 三字节) - 对二进制数据(如
BLOB)同样适用:HEX(blob_col)可用于日志或调试查看原始字节 - 别误以为它是加密:
HEX()可逆、无密钥、无混淆,仅编码表示 - 空字符串返回空:
HEX('')→'';HEX(NULL)→NULL
UNHEX() 是 HEX() 的严格逆操作,但有隐含前提
它只接受长度为偶数的十六进制字符串(只含 0–9、A–F、a–f),且必须是合法 hex 字符序列。失败时直接返回 NULL,不会报错 —— 这是容易漏掉的坑。
- 输入长度为奇数(如
'ABC')→ 返回NULL,不是截断也不是补零 - 含非法字符(如
'GX12')→ 返回NULL,静默失败 - 大小写不敏感:
UNHEX('abCD')和UNHEX('ABcd')结果一致 - 常和
HEX()配合做“临时序列化”:比如把用户 ID 拼接后 hex 存字段,再 unhex 恢复 —— 但仅限 MySQL 内部流转,跨系统需约定格式
跨数据库迁移时 HEX/UNHEX 无法直接替换
PostgreSQL 用 encode(data, 'hex') 和 decode(hex_str, 'hex');SQL Server 用 CONVERT(VARCHAR, data, 2) 和 CONVERT(VARBINARY, hex_str, 2);SQLite 用 hex()(小写)和 unhex()(但要求输入为 BLOB,行为略有差异)。硬搬 MySQL 写法必然出错。
- MySQL 的
HEX('abc')→'616263',PostgreSQL 的encode('abc'::bytea, 'hex')→ 同样'616263',表面一致但类型系统不同 - PostgreSQL 的
decode()对非法 hex 报错(ERROR: invalid input syntax for type bytea),而 MySQL 的UNHEX()静默返回NULL - 如果业务逻辑依赖
UNHEX()返回NULL表示失败,迁到 PostgreSQL 必须改用TRY_CAST或异常捕获兜底
真正麻烦的不是函数本身,而是把 HEX/UNHEX 当作“通用编码方案”来用 —— 它只在 MySQL 里可靠,且不处理字符集隐式转换。比如从 utf8mb4 列读出再 UNHEX(HEX()),看似绕一圈,实则可能因连接字符集设置不同导致双编码。

















