MySQL中LENGTH()返回字节数而非字符数,如UTF8mb4下'好'返回4;需字符数时应使用CHAR_LENGTH();SQL Server用LEN()(返回字符数),PostgreSQL的LENGTH()也返回字符数,OCTET_LENGTH()才返回字节数。

MySQL 用 LENGTH(),不是 LEN()
MySQL 没有 LEN() 函数,直接写会报错 ERROR 1305 (42000): FUNCTION db.LEN does not exist。必须用 LENGTH() —— 它返回的是字节数,不是字符数。比如中文 UTF8mb4 编码下,一个汉字占 4 字节,LENGTH('好') 返回 4,不是 1。
常见误用场景:想统计「有几个字符」却用了 LENGTH(),结果在含中文、emoji 的字段上严重偏高。
- 要按字符数统计(如“用户昵称有几个字”),改用
CHAR_LENGTH()或CHARACTER_LENGTH()(二者等价) -
LENGTH()适合判断存储开销、做字节截断(如限制 HTTP Header 长度)、或配合utf8mb4_bin排序规则做精确字节比较 - 建表时若字段定义为
VARCHAR(10),实际能存的字符数取决于编码和内容,LENGTH()帮你确认是否真超了底层字节限制
SQL Server 和 Azure SQL 必须用 LEN(),LENGTH() 无效
SQL Server 不认 LENGTH(),写上去会提示 Invalid column name 'LENGTH' 或解析失败。它只支持 LEN(),且该函数返回字符数(自动忽略末尾空格)。
典型陷阱:从 MySQL 迁移 SQL 时直接替换函数名,没改逻辑,导致长度判断偏差;或者误以为 LEN() 也计算空格,结果过滤条件漏掉带空格的数据。
-
LEN('abc ')返回3,不是6;需要包含空格请先用RTRIM()+DATALENGTH()组合 -
DATALENGTH()返回字节数,对NVARCHAR字段每个字符算 2 字节(UTF-16),LEN()则统一按字符计 - 在 WHERE 条件里用
LEN(name) > 10是安全的,但别在 JOIN ON 中依赖它做高频计算,可能影响索引使用
PostgreSQL 用 LENGTH(),但行为和 MySQL 完全不同
PostgreSQL 的 LENGTH() 返回字符数,不是字节数 —— 这点和 MySQL 相反,但和 SQL Server 的 LEN() 一致。例如 LENGTH('数据库') 返回 3,不是字节数 9(UTF8 下每个汉字 3 字节)。
容易混淆的点:看到名字像 MySQL 就默认是字节,结果在迁移或跨数据库写视图时出错。
- 需要字节数?用
OCTET_LENGTH()—— 这才是 PostgreSQL 的“字节版LENGTH()” -
CHAR_LENGTH()是标准 SQL 别名,PostgreSQL 也支持,可读性更强,推荐优先用 - 对
TEXT字段调用LENGTH()没性能问题,但对加了表达式索引的字段(如LENGTH(title)),注意索引是否真被命中
跨数据库兼容写法几乎不存在,别硬套
没有一种写法能在 MySQL / SQL Server / PostgreSQL 里都用同一个函数名且语义一致。强行用预处理或视图抽象,反而让逻辑更难调试。
真实项目中更稳妥的做法是:在 ORM 层或应用代码里统一封装,或在 SQL 片段生成阶段根据方言注入对应函数。
- 不要在迁移脚本里写“通用 LENGTH”,先明确目标库再选函数
- 如果必须写兼容 SQL(比如给多个客户部署),用条件注释(MySQL 的
/*!50000 LENGTH() */)或拆成多个分支 - 最常被忽略的是 NULL 处理:
LENGTH(NULL)、LEN(NULL)、CHAR_LENGTH(NULL)全部返回NULL,不是0,WHERE 中需显式写IS NOT NULL

















