LEN函数不包括SQL Server中的尾随空格

时间:2010-01-08 04:52:28

标签: sql-server

我在SQL Server 2005中有以下测试表:

CREATE TABLE [dbo].[TestTable]
(
 [ID] [int] NOT NULL,
 [TestField] [varchar](100) NOT NULL
) 

填充:

INSERT INTO TestTable (ID, TestField) VALUES (1, 'A value');   -- Len = 7
INSERT INTO TestTable (ID, TestField) VALUES (2, 'Another value      '); -- Len = 13 + 6 spaces

当我尝试使用SQL Server LEN()函数查找TestField的长度时,它不计算尾随空格 - 例如:

-- Note: Also results the grid view of TestField do not show trailing spaces (SQL Server 2005).
SELECT 
 ID, 
 TestField, 
 LEN(TestField) As LenOfTestField, -- Does not include trailing spaces
FROM 
 TestTable

如何在长度结果中包含尾随空格?

10 个答案:

答案 0 :(得分:117)

Microsoft在MSDN中http://msdn.microsoft.com/en-us/library/ms190329(SQL.90).aspx清楚地记录了这一点,其中指出LEN“返回指定字符串表达式的字符数,不包括尾随空白”。但是,如果你不小心,这是一个很容易错过的细节。

您需要使用DATALENGTH函数 - 请参阅http://msdn.microsoft.com/en-us/library/ms173486(SQL.90).aspx - “返回用于表示任何表达式的字节数”。

示例:

SELECT 
    ID, 
    TestField, 
    LEN(TestField) As LenOfTestField,           -- Does not include trailing spaces
    DATALENGTH(TestField) As DataLengthOfTestField      -- Shows the true length of data, including trailing spaces.
FROM 
    TestTable

答案 1 :(得分:76)

你可以使用这个技巧:

LEN(Str +'x') - 1

答案 2 :(得分:12)

  

“如何在长度结果中包含尾随空格?”

你得到某人提交SQL Server增强请求/错误报告,因为几乎所有列出这个非常简单的问题的解决方法都存在一些缺陷或效率低下。这在SQL Server 2012中似乎仍然如此。自动修剪功能可能源于ANSI / ISO SQL-92,但似乎存在一些漏洞(或者没有计算它们)。

请在这里投票“添加设置,以便LEN计算尾随空格”:

https://feedback.azure.com/forums/908035-sql-server/suggestions/34673914-add-setting-so-len-counts-trailing-whitespace

退休连接链接: https://connect.microsoft.com/SQLServer/feedback/details/801381

答案 3 :(得分:12)

我使用这种方法:

TeX

我比DATALENGTH更喜欢这个,因为这适用于不同的数据类型,我更喜欢在最后添加一个字符,因为你不必担心你的字符串已经达到最大长度的边缘情况

注意:我会在针对非常大的数据集使用之前测试性能;虽然我只是针对2M行进行了测试,但是如果没有REPLACE,它就不会慢于LEN ......

答案 4 :(得分:8)

两个最高投票答案存在问题。建议DATALENGTH的答案容易出现程序员错误。对于DATALENGTH类型,NVARCHAR的结果必须除以2,但对于VARCHAR类型则不能。这需要了解您获得长度的类型,如果该类型发生变化,您必须努力更改您使用的地点DATALENGTH

最受欢迎的答案也存在问题(我承认这是我首选的方法,直到这个问题出现在我身上)。如果您获得的长度是NVARCHAR(4000)类型,并且它实际上包含4000个字符的字符串,则SQL将忽略附加的字符,而不是隐式地将结果强制转换为NVARCHAR(MAX)。最终结果是长度不正确。 VARCHAR(8000)也会发生同样的事情。

我发现的作品几乎和普通的LEN一样快,对于大字符串来说比LEN(@s + 'x') - 1快,并且不假设基础字符宽度如下:< / p>

DATALENGTH(@s) / DATALENGTH(LEFT(LEFT(@s, 1) + 'x', 1))

这将获取数据长度,然后除以字符串中单个字符的数据长度。添加&#39; x&#39;涵盖了字符串为空的情况(在这种情况下,它将除以零)。无论@sVARCHAR还是NVARCHAR,这都有效。在字符串很大的时候,在追加之前执行1个字符的LEFT。但问题是,对于包含代理项对的字符串,它无法正常工作。

使用REPLACE(@s,' ','x')对接受的答案的评论中提到了另一种方法。该技术给出了正确的答案,但是当字符串很大时,它比其他技术慢几个数量级。

考虑到代理对对使用DATALENGTH的任何技术引入的问题,我认为最安全的方法可以得到我所知道的正确答案:

LEN(CONVERT(NVARCHAR(MAX), @s) + 'x') - 1

这比REPLACE技术快,并且使用更长的字符串要快得多。基本上这种技术是LEN(@s + 'x') - 1技术,但是对边缘情况的保护,其中字符串的长度为4000(对于nvarchar)或8000(对于varchar),因此即使对此也给出了正确的答案。它还应该正确处理具有代理对的字符串。

答案 5 :(得分:5)

您还需要确保使用尾随空白实际保存数据。当ANSI PADDING关闭(非默认)时:

  

字符值中的尾随空白   插入到varchar列中   修整。

答案 6 :(得分:4)

LEN默认情况下会删除尾随空格,因此我发现这会将它们移动到前面

(LEN(REVERSE(TestField))

所以,如果你愿意,你可以说

SELECT
t.TestField,
LEN(REVERSE(t.TestField)) AS [Reverse],
LEN(t.TestField) AS [Count]
FROM TestTable t
WHERE LEN(REVERSE(t.TestField)) <> LEN(t.TestField)

当然不要将它用于领导空间。

答案 7 :(得分:1)

如果您不喜欢字符串连接,则应定义一个返回String的Length字段的CLR函数。 我在生产用例中使用LEN('x' + @string + 'x') - 2

答案 8 :(得分:0)

如果由于n / varchar问题而不喜欢DATALENGTH,那么:

select DATALENGTH(@var)/isnull(nullif(DATALENGTH(left(@var,1)),0),1)

只是

select DATALENGTH(@var)/DATALENGTH(left(@var,1))

包含被零除保护。

除以单个字符的DATALENGTH,我们得到标准化的长度。

(当然,如果这是一个问题,仍然存在代理对的问题。)

答案 9 :(得分:-2)

使用 SELECT DATALENGTH('string')