Tsql 传递给子字符串函数的长度参数无效

Tsql 传递给子字符串函数的长度参数无效,tsql,Tsql,我已经编写了查询,它正在工作: declare @word as nvarchar (20) set @word = 'victOR aALEXander' select upper(left(@word, 1)) + lower(SUBSTRING(@word,2,charindex(' ', @word)-2)) + ' ' + upper(left(substring(@word,charindex(' ', @word)+1,len(@word)-1),1)) + lower(SUB

我已经编写了查询,它正在工作:

declare @word as nvarchar (20)
set @word = 'victOR aALEXander'
select upper(left(@word, 1)) + lower(SUBSTRING(@word,2,charindex(' ', @word)-2)) + ' ' + 
upper(left(substring(@word,charindex(' ', @word)+1,len(@word)-1),1)) 
+ lower(SUBSTRING(@word,charindex(' ', @word)+2, len(@word)))
我创建了以下函数:

  alter function letters ( @word as nvarchar(20))
returns varchar(20) as begin
return upper(left(@word, 1)) + lower(SUBSTRING(@word,2,charindex(' ', @word)-2)) + ' ' + 
upper(left(substring(@word,charindex(' ', @word)+1,len(@word)-1),1)) 
+ lower(SUBSTRING(@word,charindex(' ', @word)+2, len(@word))) end
Create Function dbo.Proper(@Data VarChar(8000))
Returns VarChar(8000)
As
Begin
  Declare @Position Int

  Select @Data = Stuff(Lower(@Data), 1, 1, Upper(Left(@Data, 1))),
         @Position = PatIndex('%[^a-zA-Z][a-z]%', @Data COLLATE Latin1_General_Bin)

  While @Position > 0
    Select @Data = Stuff(@Data, @Position, 2, Upper(SubString(@Data, @Position, 2))),
           @Position = PatIndex('%[^a-zA-Z][a-z]%', @Data COLLATE Latin1_General_Bin)

  Return @Data
End
最后,我做了:

select dbo.letters(users)
from dbo.tempdb
我有:

传递给子字符串函数的长度参数无效


为什么?

参数
@word
的字符计数小于子字符串计数。此外,参数可以是
null

如果开头和结尾有空格,也可以尝试修剪:

alter function letters ( @word as nvarchar(20))
returns varchar(20) as 
begin
set @word = ltrim(rtrim(@word))
return upper(left(@word, 1)) + lower(SUBSTRING(@word,2,charindex(' ', @word)-2)) + ' ' + 
upper(left(substring(@word,charindex(' ', @word)+1,len(@word)-1),1)) 
+ lower(SUBSTRING(@word,charindex(' ', @word)+2, len(@word))) 
end

如果此查询有效,请重试。但是,如果有多个“”,则此查询将失败

declare @word as nvarchar (20)

set @word = 'alex' -- 'victOR aALEXander'

select 
upper(left(@word, 1)) + 
CASE WHEN charindex(' ', @word)>0 THEN  lower(SUBSTRING(@word,2,charindex(' ', @word)-2)) + ' '
+ upper(left(substring(@word,charindex(' ', @word)+1,len(@word)-1),1)) 
+ lower(SUBSTRING(@word,charindex(' ', @word)+2, len(@word)))
 ELSE lower(SUBSTRING(@word,2,len(@word)-1)) END  
尝试此功能:

  alter function letters ( @word as nvarchar(20))
returns varchar(20) as begin
return upper(left(@word, 1)) + lower(SUBSTRING(@word,2,charindex(' ', @word)-2)) + ' ' + 
upper(left(substring(@word,charindex(' ', @word)+1,len(@word)-1),1)) 
+ lower(SUBSTRING(@word,charindex(' ', @word)+2, len(@word))) end
Create Function dbo.Proper(@Data VarChar(8000))
Returns VarChar(8000)
As
Begin
  Declare @Position Int

  Select @Data = Stuff(Lower(@Data), 1, 1, Upper(Left(@Data, 1))),
         @Position = PatIndex('%[^a-zA-Z][a-z]%', @Data COLLATE Latin1_General_Bin)

  While @Position > 0
    Select @Data = Stuff(@Data, @Position, 2, Upper(SubString(@Data, @Position, 2))),
           @Position = PatIndex('%[^a-zA-Z][a-z]%', @Data COLLATE Latin1_General_Bin)

  Return @Data
End

无论数据中是否有空格、撇号或其他内容,此函数都能正常工作。不幸的是,它不会把麦克唐纳变成麦克唐纳,也不会把奥布莱恩变成奥布莱恩。但是,它适用于任何只有1个大写字母的单词。

几年前有一篇关于适当大小写函数的博客。全世界有很多人都在使用它。我建议你至少试一试。