首页 > 解决方案 > 为什么 LEN( char(32) ) = 0 在 T-SQL 中?

问题描述

我想编写一个函数来计算文本字符串中分隔符或任何子字符串(可能是空格)的数量,如果分隔符为空或为空,则会引发 hack 错误:

if len(@lookfor)=0 or @lookfor is null return Cast('substring must not be null or empty' as int)

但是,如果使用 @lookfor = ' ' 调用该函数,则会引发错误。

我知道 DATALENGTH()。只是好奇为什么如果前面没有任何东西,单个空格会被视为“尾随”。

标签: sql-servertsql

解决方案


我知道 DATALENGTH()。只是好奇为什么如果前面没有任何东西,单个空格会被视为“尾随”。

它是尾随的,因为它位于字符串的末尾。它也是领先的,因为它是一开始的。

但是,如果使用 @lookfor = '' 调用该函数,则会引发错误

让很多人对 SQL 感到困惑的是 '' = ' '; 注意这个查询:

DECLARE @blank VARCHAR(10) = '', @space VARCHAR(10) = CHAR(32);
SELECT CASE WHEN @blank = @space THEN 'That the...!?!?' END;

您可以将 @space 更改为 CHAR(32)+CHAR(32)+.... 并且 @space 和 @blank 仍然相等。

使事情复杂一点请注意,DATALENGTH当它是 VARCHAR(N) 时,空白/空值的值为 0,但 CHAR(N) 值时的 DATALENGTH 为 N。换句话说, SELECT DATALENGTH(CAST('' AS CHAR(1)))返回 1 并SELECT DATALENGTH(CAST('' AS CHAR(10)))返回 10。

这意味着如果您的分隔符变量是 CHAR(1) - 那会让您感到困惑。这是适合您的功能:

CREATE FUNCTION dbo.CountDelimiters(@string VARCHAR(8000), @delimiter VARCHAR(1))
RETURNS TABLE WITH SCHEMABINDING AS RETURN
SELECT DCount = MAX(DATALENGTH(@string)-LEN(REPLACE(@string,@delimiter,'')))
WHERE  DATALENGTH(@delimiter) > 0;

请注意,@delimter 是 VARCHAR(1) 而不是CHAR 数据类型。

计算@string 中分隔符的公式是:

DATALENGTH(@string)-LEN(REPLACE(@string,@delimiter,'')) 或者

(DATALENGTH(@string)-LEN(REPLACE(@string,@delimiter,'')))/DATALENGTH(@delimiter)处理大于 1 的分隔符时。

WHERE DATALENGTH(@delimiter) > 0将强制函数忽略 NULL 或空白值。这称为启动谓词

放置一个 MAXDATALENGTH(@string)-LEN(REPLACE(@string,@delimiter,''))会强制函数在您传递一个空白或 NULL 值的情况下重新返回一个 NULL 值。

这将为我的字符串中的空格数返回 10:

SELECT f.DCount FROM dbo.CountDelimiters('one space  two spaces   three   ', CHAR(32)) AS f;

针对表格,您将使用这样的函数(请注意,我正在计算字母“A”出现的次数:

-- Sample Strings
DECLARE @table TABLE (SomeText VARCHAR(36));
INSERT @table VALUES('ABCABC'),('XXX'),('AAA'),(''),(NULL);

SELECT      t.SomeText, f.DCount    
FROM        @table                               AS t
CROSS APPLY dbo.CountDelimiters(t.SomeText, 'A') AS f;

返回:

SomeText                             DCount
------------------------------------ -----------
ABCABC                               2
XXX                                  0
AAA                                  3
                                     0
NULL                                 NULL

推荐阅读