SQL Server LEN函数报告错误的结果

3
假设我们将一个整数转换成二进制值,如cast(120 as binary(8))或任何其他整数转换为binary(8)
通常情况下,我们期望 len(cast(120 as binary(8))) = 8 ,这是正确的,除非我们尝试使用数字32,其中select len(cast(32 as binary(8)))返回7!
这是SQL Server的错误吗?
1个回答

4

不是一个 bug,这是关于 LEN 函数的工作方式。LEN 函数:

返回指定字符串表达式的字符数,不包括尾随空格。

"尾随空格" 的定义似乎基于数据类型而有所不同。对于二进制值,尾随空格是二进制 表示 中的 "20"。在 LEN 的 BOL 条目中有一条注释,其中写道,

使用 LEN 返回编码到给定字符串表达式中的字符数,并使用 DATALENGTH 返回给定字符串表达式的字节数。这些输出可能因 [值] 使用的数据类型和编码类型而有所不同。有关不同编码类型之间存储差异的更多信息,请参见排序规则和 Unicode 支持。

对于二进制值,长度 (LEN) 对以 20 结尾的二进制值减少 1,对以 2020 结尾的值减少 2,等等。再次说明它将该值视为尾随空格。 DATALENGTH 可以解决这个问题。请注意此 SQL:

DECLARE 
  @string VARCHAR(100) = '1234567 ',
  @binary BINARY(8)    = 32;

SELECT [Type] = 'string',   [Len] = LEN(@string), [Datalength] = DATALENGTH(@string)
UNION ALL
SELECT [Type] = 'binary(8)', [Len] = LEN(@binary), [Datalength] = DATALENGTH(@binary);

返回值:

Type      Len         Datalength
--------- ----------- -----------
string    7           8
binary(8) 7           8

使用我的rangeAB函数(在这里),我创建了以下查询:

SELECT 
  N            = r.RN,
  Binaryvalue  = CAST(r.RN AS binary(8)), 
  [Len]        = LEN(CAST(r.RN AS binary(8))),
  [DataLength] = DATALENGTH(CAST(r.RN AS binary(8)))
FROM     dbo.rangeAB(0,10000,1,0) AS r
WHERE    LEN(CAST(r.RN AS binary(8))) <> 8
ORDER BY N;

请注意以下结果:
N                    Binaryvalue        Len         DataLength
-------------------- ------------------ ----------- -----------
32                   0x0000000000000020 7           8
288                  0x0000000000000120 7           8
544                  0x0000000000000220 7           8
800                  0x0000000000000320 7           8
1056                 0x0000000000000420 7           8
1312                 0x0000000000000520 7           8
1568                 0x0000000000000620 7           8
1824                 0x0000000000000720 7           8
2080                 0x0000000000000820 7           8
2336                 0x0000000000000920 7           8
2592                 0x0000000000000A20 7           8
2848                 0x0000000000000B20 7           8
3104                 0x0000000000000C20 7           8
3360                 0x0000000000000D20 7           8
3616                 0x0000000000000E20 7           8
3872                 0x0000000000000F20 7           8
4128                 0x0000000000001020 7           8
4384                 0x0000000000001120 7           8
4640                 0x0000000000001220 7           8
4896                 0x0000000000001320 7           8
5152                 0x0000000000001420 7           8
5408                 0x0000000000001520 7           8
5664                 0x0000000000001620 7           8
5920                 0x0000000000001720 7           8
6176                 0x0000000000001820 7           8
6432                 0x0000000000001920 7           8
6688                 0x0000000000001A20 7           8
6944                 0x0000000000001B20 7           8
7200                 0x0000000000001C20 7           8
7456                 0x0000000000001D20 7           8
7712                 0x0000000000001E20 7           8
7968                 0x0000000000001F20 7           8
8224                 0x0000000000002020 6           8
8480                 0x0000000000002120 7           8
8736                 0x0000000000002220 7           8
8992                 0x0000000000002320 7           8
9248                 0x0000000000002420 7           8
9504                 0x0000000000002520 7           8
9760                 0x0000000000002620 7           8

请注意,CAST(8224 AS binary(8)LEN为6; 因为8224以2020结尾,被视为两个空格。
8224                 0x0000000000002020 6           8

1
非常感谢你的回答,Alan。虽然我知道dataLength函数,但我并不知道Len函数在二进制数据中的作用和性质。我已经在我的代码中将它替换为DataLenght。 - POLY

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接