len返回字符数且裁剪尾随空格,datalength返回字节数且不作任何转换;前者面向语义,后者面向存储。

LEN 返回字符数,DATALENGTH 返回字节数 —— 这是根本差异,不是 bug,是设计使然。
LEN 会自动裁剪尾随空格,且只认“字符”
当你传入 'abc '(末尾带 3 个空格)时,LEN 返回 3,不是 6。它把字符串当作文本语义处理:先隐式转成字符串(如果输入是 int 或 binary),再移除所有尾部空格,最后数“可见字符个数”。
-
LEN(N'你好')→2(两个 Unicode 字符) -
LEN('你好')→2(非 Unicode 下汉字仍算 1 个字符) -
LEN(@x)中 @x 是char(10)且值为'abc'→ 仍返回3(固定长度类型也裁尾空) -
LEN(12345)→5(先把 int 转成字符串'12345'再计数)
DATALENGTH 不做任何语义转换,只看内存占多少字节
DATALENGTH 就像用尺子量内存:不管你是字符串、整数、XML 还是 varbinary,它直接读底层存储长度。不裁空格、不转类型、不理解“字符”概念。
-
DATALENGTH(N'abc')→6(每个 Unicode 字符占 2 字节) -
DATALENGTH('abc')→3(单字节编码) -
DATALENGTH('abc ')→6(含 3 个尾空格,各占 1 字节) -
DATALENGTH(12345)→4(int类型固定占 4 字节) -
DATALENGTH(0x616263)→3(3 字节二进制数据)
遇到 NULL、text/nvarchar(max) 或排序规则时行为一致但结果易混淆
两者对 NULL 都返回 NULL;都支持 max 类型并可能返回 bigint;但在 SC 排序规则下,LEN 把 UTF-16 代理项对(如某些 emoji)当作 1 个字符,而 DATALENGTH 仍按实际字节数算(通常是 4)。这意味着:
- 查字段是否为空?别只用
LEN(col) = 0—— 如果col是''或全是空格,LEN都是0,但业务上可能不算“空” - 判断字符串是否超长入库?用
DATALENGTH更准,尤其字段是nvarchar且涉及中英文混合 - 对
text/ntext(已弃用)或xml,LEN会报错,DATALENGTH可用
真正容易出错的地方,是把 LEN 当作“真实存储长度”来用,或者在比较不同编码字段时混用两者。它们解决的问题完全不同:一个数“人眼看到几个字”,一个量“硬盘存了几字节”。选哪个,取决于你手头的问题到底在问什么。










