将SQL Server中字符串中每个单词的第一个字母大写的最佳方法是什么。
答案 0 :(得分:70)
来自http://www.sql-server-helper.com/functions/initcap.aspx
CREATE FUNCTION [dbo].[InitCap] ( @InputString varchar(4000) )
RETURNS VARCHAR(4000)
AS
BEGIN
DECLARE @Index INT
DECLARE @Char CHAR(1)
DECLARE @PrevChar CHAR(1)
DECLARE @OutputString VARCHAR(255)
SET @OutputString = LOWER(@InputString)
SET @Index = 1
WHILE @Index <= LEN(@InputString)
BEGIN
SET @Char = SUBSTRING(@InputString, @Index, 1)
SET @PrevChar = CASE WHEN @Index = 1 THEN ' '
ELSE SUBSTRING(@InputString, @Index - 1, 1)
END
IF @PrevChar IN (' ', ';', ':', '!', '?', ',', '.', '_', '-', '/', '&', '''', '(')
BEGIN
IF @PrevChar != '''' OR UPPER(@Char) != 'S'
SET @OutputString = STUFF(@OutputString, @Index, 1, UPPER(@Char))
END
SET @Index = @Index + 1
END
RETURN @OutputString
END
GO
这里有一个更简单/更小的(但如果任何行没有空格则不起作用,“传递给RIGHT函数的长度参数无效。”):
答案 1 :(得分:1)
我已经使用了很长一段时间的变体是:
CREATE FUNCTION [widget].[properCase](@string varchar(8000)) RETURNS varchar(8000) AS
BEGIN
SET @string = LOWER(@string)
DECLARE @i INT
SET @i = ASCII('a')
WHILE @i <= ASCII('z')
BEGIN
SET @string = REPLACE( @string, ' ' + CHAR(@i), ' ' + CHAR(@i-32))
SET @i = @i + 1
END
SET @string = CHAR(ASCII(LEFT(@string, 1))-32) + RIGHT(@string, LEN(@string)-1)
RETURN @string
END
如果您愿意,可以轻松修改以处理空格以外的项目后的字符。
答案 2 :(得分:1)
另一种不使用循环的解决方案 - 基于纯集的方法和递归CTE
create function [dbo].InitCap (@value varchar(max))
returns varchar(max) as
begin
declare
@separator char(1) = ' ',
@result varchar(max) = '';
with r as (
select value, cast(null as varchar(max)) [x], cast('' as varchar(max)) [char], 0 [no] from (select rtrim(cast(@value as varchar(max))) [value]) as j
union all
select right(value, len(value)-case charindex(@separator, value) when 0 then len(value) else charindex(@separator, value) end) [value]
, left(r.[value], case charindex(@separator, r.value) when 0 then len(r.value) else abs(charindex(@separator, r.[value])-1) end ) [x]
, left(r.[value], 1)
, [no] + 1 [no]
from r where value > '')
select @result = @result +
case
when ascii([char]) between 97 and 122
then stuff(x, 1, 1, char(ascii([char])-32))
else x
end + @separator
from r where x is not null;
set @result = rtrim(@result);
return @result;
end
答案 3 :(得分:1)
这是最简单的单行代码。
select
LEFT(column, 1)+ lower(RIGHT(column, len(column)-1) )
from [tablename]
答案 4 :(得分:1)
如果您正在Oracle / PLSQL中寻找相同问题的答案,则可以使用函数INITCAP。以下是表部门中属性 dname 的示例,该表具有值(“销售”,“管理”,“生产”,“发展”)。>
SQL> select INITCAP(dname) from department;
INITCAP(DNAME)
--------------------------------------------------
Sales
Management
Production
Development
答案 5 :(得分:0)
建议的函数工作正常,但是,如果您不想创建任何函数,我就是这样做的-
select ID,Name
,string_agg(concat(upper(substring(value,1,1)),lower(substring(value,2,len(value)-1))),' ') as ModifiedName
from Table_Customer
cross apply String_Split(replace(trim(Name),' ',' '),' ')
where Name is not null
group by ID,Name;
上面的查询按空格(' ')分割单词并创建不同的行,每个行都有一个子字符串,然后将每个子字符串的第一个字母转换为大写并保持为小写。最后一步是根据键进行字符串聚合。
希望你觉得它有用!
答案 6 :(得分:0)
就这么简单:
DECLARE @Name VARCHAR(10) = 'merin';
SELECT @Name AS Name, REPLACE(@Name, LEFT(@Name, 1), UPPER(LEFT(@Name, 1))) AS CapitalizedName
答案 7 :(得分:0)
SELECT dbo.ProperCase('Xyz is AFTER qrst')
答案 8 :(得分:0)
GO
CREATE FUNCTION [dbo].[Capitalize](@text NVARCHAR(MAX)) RETURNS NVARCHAR(MAX) AS
BEGIN
DECLARE @result NVARCHAR(MAX) = '';
DECLARE @c NVARCHAR(1);
DECLARE @i INT = 1;
DECLARE @isPrevSpace BIT = 1;
WHILE @i <= LEN(@text)
BEGIN
SET @c = SUBSTRING(@text, @i, 1);
SET @result += IIF(@isPrevSpace = 1, UPPER(@c), LOWER(@c));
SET @isPrevSpace = IIF(@c LIKE '[ -]', 1, 0);
SET @i += 1;
END
RETURN @result;
END
GO
DECLARE @sentence NVARCHAR(100) = N'i-thINK-this soLUTION-works-LiKe-a charm';
PRINT dbo.Capitalize(@sentence);
-- I-Think-This Solution-Works-Like-A Charm
答案 9 :(得分:0)
;WITH StudentList(Name) AS (
SELECT CONVERT(varchar(50), 'Carl-VAN')
UNION SELECT 'Dean o''brian'
UNION SELECT 'Andrew-le-Smith'
UNION SELECT 'Eddy thompson'
UNION SELECT 'BOBs-your-Uncle'
), Student AS (
SELECT CONVERT(varchar(50), UPPER(LEFT(Name, 1)) + LOWER(SUBSTRING(Name, 2, LEN(Name)))) Name,
pos = PATINDEX('%[-'' ]%', Name)
FROM StudentList
UNION ALL
SELECT CONVERT(varchar(50), LEFT(Name, pos) + UPPER(SUBSTRING(Name, pos + 1, 1)) + SUBSTRING(Name, pos + 2, LEN(Name))) Name,
pos = CASE WHEN PATINDEX('%[-'' ]%', RIGHT(Name, LEN(Name) - pos)) = 0 THEN 0 ELSE pos + PATINDEX('%[-'' ]%', RIGHT(Name, LEN(Name) - pos)) END
FROM Student
WHERE pos > 0
)
SELECT Name
FROM Student
WHERE pos = 0
ORDER BY Name
这将导致:
使用基于递归CTE集的查询应执行过程while循环查询。 在这里,我也将自己设为3个不同的字符[-'],而不是1个更高级的示例。通过使用PATINDEX,我可以查找许多字符。您也可以在单个字符上使用CHARINDEX,并且该函数除了第三个参数StartFromPosition之外,因此我可以进一步简单地将pos公式的第二部分递归为(假设有空格):pos = CHARINDEX(''',Name,pos + 1)。
答案 10 :(得分:0)
在 SQL Server 2016 + 上,使用JSON可以保证单词的顺序:
CREATE FUNCTION [dbo].[InitCap](@Text NVARCHAR(MAX))
RETURNS NVARCHAR(MAX)
AS
BEGIN
RETURN STUFF((
SELECT ' ' + UPPER(LEFT(s.value,1)) + LOWER(SUBSTRING(s.value,2,LEN(s.value)))
FROM OPENJSON('["' + REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(@Text,'\','\\'),'"','\"'),CHAR(9),'\t'),CHAR(10),'\n'),' ','","') + '"]') s
ORDER BY s.[key]
FOR XML PATH(''),TYPE).value('(./text())[1]','NVARCHAR(MAX)'),1,1,'');
END
答案 11 :(得分:0)
fname是列名,如果fname的值是akhil,则UPPER(left(fname,1))提供大写形式首字母(A)和子字符串函数SUBSTRING(fname,2,LEN(fname))提供(khil)结合使用+然后结果是(Akhil)
select UPPER(left(fname,1))+SUBSTRING(fname,2,LEN(fname)) as fname
FROM [dbo].[akhil]
答案 12 :(得分:0)
我一直在寻找最佳的大写方式,然后重新创建简单的sql脚本
如何使用SELECT dbo.Capitalyze(“这是一个带有多个空格的测试”)
结果“这是一个具有多个空格的测试”
创建功能Capitalyze(@input varchar(100)) 返回varchar(100) 如 开始
declare @index int=0
declare @char as varchar(1)=' '
declare @prevCharIsSpace as bit=1
declare @Result as varchar(100)=''
set @input=UPPER(LEFT(@input,1))+LOWER(SUBSTRING(@input, 2, LEN(@input)))
set @index=PATINDEX('% _%',@input)
if @index=0
set @index=len(@input)
set @Result=substring(@input,0,@index+1)
WHILE (@index < len(@input))
BEGIN
SET @index = @index + 1
SET @char=substring(@input,@index,1)
if (@prevCharIsSpace=1)
begin
set @char=UPPER(@char)
if (@char=' ')
set @char=''
end
if (@char=' ')
set @prevCharIsSpace=1
else
set @prevCharIsSpace=0
set @Result=@Result+@char
--print @Result
END
--print @Result
return @Result
结束
答案 13 :(得分:0)
仅适用于英语数据。
从性能的角度来看超级无效,但从生产率的角度来看效率很高。用作一次性转换器:
SELECT
REPLACE(
REPLACE(
REPLACE(
REPLACE(
REPLACE(
REPLACE(
REPLACE(
REPLACE(
REPLACE(
REPLACE(
REPLACE(
REPLACE(
REPLACE(
REPLACE(
REPLACE(
REPLACE(
REPLACE(
REPLACE(
REPLACE(
REPLACE(
REPLACE(
REPLACE(
REPLACE(
REPLACE(
REPLACE(
REPLACE(
UPPER(LEFT(City,1))+LOWER(SUBSTRING(City,2,LEN(City)))
,' a', ' A')
,' b', ' B')
,' c', ' C')
,' d', ' D')
,' e', ' E')
,' f', ' F')
,' g', ' G')
,' h', ' H')
,' i', ' I')
,' j', ' J')
,' k', ' K')
,' l', ' L')
,' m', ' M')
,' n', ' N')
,' o', ' O')
,' p', ' P')
,' q', ' Q')
,' r', ' R')
,' s', ' S')
,' t', ' T')
,' u', ' U')
,' v', ' V')
,' w', ' W')
,' x', ' X')
,' y', ' Y')
,' z', ' Z')
FROM [Dictionaries].[dbo].[Cities]
WHERE Country = 'US' AND City like '% %'
ORDER BY City
答案 14 :(得分:0)
{{1}}
END
答案 15 :(得分:0)
作为表值函数:
CREATE FUNCTION dbo.InitCap(@v AS VARCHAR(MAX))
RETURNS TABLE
AS
RETURN
WITH a AS (
SELECT (
SELECT UPPER(LEFT(value, 1)) + LOWER(SUBSTRING(value, 2, LEN(value))) AS 'data()'
FROM string_split(@v, ' ')
FOR XML PATH (''), TYPE) ret)
SELECT CAST(a.ret AS varchar(MAX)) ret from a
GO
请注意,string_split
需要COMPATIBILITY_LEVEL
130。
答案 16 :(得分:-1)
IF OBJECT_ID ('dbo.fnCapitalizeFirstLetterAndChangeDelimiter') IS NOT NULL
DROP FUNCTION dbo.fnCapitalizeFirstLetterAndChangeDelimiter
GO
CREATE FUNCTION [dbo].[fnCapitalizeFirstLetterAndChangeDelimiter] (@string NVARCHAR(MAX), @delimiter NCHAR(1), @new_delimeter NCHAR(1))
RETURNS NVARCHAR(MAX)
AS
BEGIN
DECLARE @result NVARCHAR(MAX)
SELECT @result = '';
IF (LEN(@string) > 0)
DECLARE @curr INT
DECLARE @next INT
BEGIN
SELECT @curr = 1
SELECT @next = CHARINDEX(@delimiter, @string)
WHILE (LEN(@string) > 0)
BEGIN
SELECT @result =
@result +
CASE WHEN LEN(@result) > 0 THEN @new_delimeter ELSE '' END +
UPPER(SUBSTRING(@string, @curr, 1)) +
CASE
WHEN @next <> 0
THEN LOWER(SUBSTRING(@string, @curr+1, @next-2))
ELSE LOWER(SUBSTRING(@string, @curr+1, LEN(@string)-@curr))
END
IF (@next > 0)
BEGIN
SELECT @string = SUBSTRING(@string, @next+1, LEN(@string)-@next)
SELECT @next = CHARINDEX(@delimiter, @string)
END
ELSE
SELECT @string = ''
END
END
RETURN @result
END
GO
答案 17 :(得分:-1)
你应该试试这个
Select INITCAP(column_name) from table_name;
这将使提到的属性条目的第一个字母大写。