我想编写一个函数来计算文本字符串中定界符或任何子字符串(可能是空格)的数量,如果定界符为null或为空,则会引发hack错误:
if len(@lookfor)=0 or @lookfor is null return Cast('substring must not be null or empty' as int)
但是如果使用@lookfor =''调用该函数,则会触发错误。
我知道DATALENGTH()。只是好奇为什么在前面没有任何内容的情况下将单个空格视为“尾随”。
答案 0 :(得分:3)
我知道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或空白值。这就是启动谓词。
在DATALENGTH(@string)-LEN(REPLACE(@string,@delimiter,''))
周围放置一个MAX会在您将其传递为空白或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
答案 1 :(得分:1)
如果字符串的末尾有一个字符,则即使该字符串前面没有其他字符,也将其视为结尾。关于主角的逻辑也是如此。
因此' '
可以被认为是带有尾部空格的空字符串(''
)。
当我开始使用SQL时,我还注意到LEN函数忽略尾随空格的行为。而且我认为(但我不确定)与LEN在与CHAR / NCHAR值一起使用时也可能表现为“正确”有关。与VARCHAR / NVARCHAR不同,CHAR / NCHAR值具有固定宽度,并且将自动用尾随空格填充。因此,当您将值'abc'
放入类型为CHAR(5)的字段/变量中时,该值将变为'abc '
,但在这种情况下LEN函数仍将“正确”返回3。
我认为这只是SQL的一个怪癖。
备注:
DATALENGTH
函数将不会忽略VARCHAR / NVARCHAR值中的尾随空格。但请注意,DATALENGTH
将返回该字段值的大小(以字节为单位)。因此,如果您使用Unicode数据(NCHAR / NVARCHAR),则DATALENGTH
函数将为值N'abc'
返回6,因为SQL Server中的每个Unicode字符都使用2个字节!