SQL Server:将所有UPPER情况设置为正确的案例/标题案例

我有一个导入所有大写的表格,我想把它转换成适当的大小写。 你有什么脚本用来完成这个?

这是一个UDF,将做的伎俩…

create function ProperCase(@Text as varchar(8000)) returns varchar(8000) as begin declare @Reset bit; declare @Ret varchar(8000); declare @i int; declare @c char(1); select @Reset = 1, @i=1, @Ret = ''; while (@i <= len(@Text)) select @c= substring(@Text,@i,1), @Ret = @Ret + case when @Reset=1 then UPPER(@c) else LOWER(@c) end, @Reset = case when @c like '[a-zA-Z]' then 0 else 1 end, @i = @i +1 return @Ret end 

您仍然必须使用它来更新您的数据。

这个function:

  • “适当的情况下”所有由“空白”分隔的“大写”字样
  • 只留下“小写字”
  • 即使是非英文字母也能正常工作
  • 是可移植的,因为它不使用最新的SQL服务器版本的奇特function
  • 可以很容易地更改为使用NCHAR和NVARCHAR来支持unicode,以及您认为合适的任何参数长度
  • 可以configuration空白的定义
 CREATE FUNCTION ToProperCase(@string VARCHAR(255)) RETURNS VARCHAR(255) AS BEGIN DECLARE @i INT -- index DECLARE @l INT -- input length DECLARE @c NCHAR(1) -- current char DECLARE @f INT -- first letter flag (1/0) DECLARE @o VARCHAR(255) -- output string DECLARE @w VARCHAR(10) -- characters considered as white space SET @w = '[' + CHAR(13) + CHAR(10) + CHAR(9) + CHAR(160) + ' ' + ']' SET @i = 1 SET @l = LEN(@string) SET @f = 1 SET @o = '' WHILE @i <= @l BEGIN SET @c = SUBSTRING(@string, @i, 1) IF @f = 1 BEGIN SET @o = @o + @c SET @f = 0 END ELSE BEGIN SET @o = @o + LOWER(@c) END IF @c LIKE @w SET @f = 1 SET @i = @i + 1 END RETURN @o END 

结果:

 dbo.ToProperCase('ALL UPPER CASE and SOME lower ÄÄ ÖÖ ÜÜ ÉÉ ØØ ĈĈ ÆÆ') ----------------------------------------------------------------- All Upper Case and Some lower Ää Öö Üü Éé Øø Cc Ææ 
 UPDATE titles SET title = UPPER(LEFT(title, 1)) + LOWER(RIGHT(title, LEN(title) - 1)) 

http://sqlmag.com/t-sql/how-title-case-column-value

如果您可以在SQL Server中启用CLR(需要2005或更高版本),那么您可以创build一个使用TextInfo.ToTitleCase内置 函数的CLR函数 ,该函数将允许您创build一个文化意识的方式,代码行。

我知道这是在这个post后期,但值得一看。 这个function对我来说都是有用的。 所以想到分享它。

 CREATE FUNCTION [dbo].[fnConvert_TitleCase] (@InputString VARCHAR(4000) ) RETURNS VARCHAR(4000) AS BEGIN DECLARE @Index INT DECLARE @Char CHAR(1) DECLARE @OutputString VARCHAR(255) SET @OutputString = LOWER(@InputString) SET @Index = 2 SET @OutputString = STUFF(@OutputString, 1, 1,UPPER(SUBSTRING(@InputString,1,1))) WHILE @Index <= LEN(@InputString) BEGIN SET @Char = SUBSTRING(@InputString, @Index, 1) IF @Char IN (' ', ';', ':', '!', '?', ',', '.', '_', '-', '/', '&','''','(') IF @Index + 1 <= LEN(@InputString) BEGIN IF @Char != '''' OR UPPER(SUBSTRING(@InputString, @Index + 1, 1)) != 'S' SET @OutputString = STUFF(@OutputString, @Index + 1, 1,UPPER(SUBSTRING(@InputString, @Index + 1, 1))) END SET @Index = @Index + 1 END RETURN ISNULL(@OutputString,'') END 

testing电话:

 select dbo.fnConvert_TitleCase(Upper('ÄÄ ÖÖ ÜÜ ÉÉ ØØ ĈĈ ÆÆ')) as test select dbo.fnConvert_TitleCase(upper('Whatever the mind of man can conceive and believe, it can achieve. – Napoleon hill')) as test 

结果:

在这里输入图像描述

我在游戏中有点晚了,但是我相信这个function更强大,可以和任何语言,包括俄语,德语,泰语,越南语等一起使用。它会在“或 – 或”之后大写。 或(或)或空间(显然:)。

 CREATE FUNCTION [dbo].[fnToProperCase]( @name nvarchar(500) ) RETURNS nvarchar(500) AS BEGIN declare @pos int = 1 , @pos2 int if (@name <> '')--or @name = lower(@name) collate SQL_Latin1_General_CP1_CS_AS or @name = upper(@name) collate SQL_Latin1_General_CP1_CS_AS) begin set @name = lower(rtrim(@name)) while (1 = 1) begin set @name = stuff(@name, @pos, 1, upper(substring(@name, @pos, 1))) set @pos2 = patindex('%[- ''.)(]%', substring(@name, @pos, 500)) set @pos += @pos2 if (isnull(@pos2, 0) = 0 or @pos > len(@name)) break end end return @name END GO 

如果您在SSIS中导入混合使用的数据,并且需要在具有适当大小写的列上执行查找,则会注意到查找源失败,查找源错误。 您还会注意到,您无法使用SQL Server 2008r2的右侧和左侧函数是用于派生列的SSIS。 这是一个适合我的解决scheme:

 UPPER(substring(input_column_name,1,1)) + LOWER(substring(input_column_name, 2, len(input_column_name)-1)) 

我知道魔鬼的细节(特别是涉及到人们的个人资料的地方),而且用大写字母的名字是非常好的,但是上面的这个麻烦就是为什么我们中间那些务实, :

SELECT UPPER('Put YoUR O'So oddLy casED McWeird-nAme von rightHERE here')

根据我的经验,人们很好的看到他们的名字……即使是在一句话的中途。

参考:俄罗斯人使用铅笔!

我在上面发表的链接是一个很好的select,它解决了主要问题:我们永远不能以编程方式解释所有情况(Smith-Jones,von Haussen,John Smith MD),至less不是以一种优雅的方式。 Tony介绍了处理这些情况的例外/中断字符的概念。 无论如何,基于Cervo的想法(上面所有低位字符都是以空格开头的),replace语句可以包含在一个基于replace的表中。 真的,任何低/高的字符组合可以插入到@alpha中,并且语句不会改变:

 declare @str nvarchar(8000) declare @alpha table (low nchar(1), up nchar(1)) set @str = 'ALL UPPER CASE and SOME lower ÄÄ ÖÖ ÜÜ ÉÉ ØØ ĈĈ ÆÆ' -- stage the alpha (needs number table) insert into @alpha -- AZ / az select nchar(n+32), nchar(n) from dbo.Number where n between 65 and 90 or n between 192 and 223 -- append space at start of str set @str = lower(' ' + @str) -- upper all lower case chars preceded by space select @str = replace(@str, ' ' + low, ' ' + up) from @Alpha select @str 

这是一个使用序列或数字表格而不是循环的版本。 您可以修改WHERE子句以适应您的个人规则,以便何时将字符转换为大写。 我刚刚列入了一个简单的集合,将大写的任何字母,除了撇号之外的非字母。 这确实意味着123apple会在“a”上有一个匹配,因为“3”不是一个字母。 如果只需要空格(空格,制表符,回车符,换行符),可以用'[' + Char(32) + Char(9) + Char(13) + Char(10) + ']' '[^az]'replace模式'[^az]' '[' + Char(32) + Char(9) + Char(13) + Char(10) + ']'


 CREATE FUNCTION String.InitCap( @string nvarchar(4000) ) RETURNS nvarchar(4000) AS BEGIN -- 1. Convert all letters to lower case DECLARE @InitCap nvarchar(4000); SET @InitCap = Lower(@string); -- 2. Using a Sequence, replace the letters that should be upper case with their upper case version SELECT @InitCap = Stuff( @InitCap, n, 1, Upper( SubString( @InitCap, n, 1 ) ) ) FROM ( SELECT (1 + n1.n + n10.n + n100.n + n1000.n) AS n FROM (SELECT 0 AS n UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) AS n1 CROSS JOIN (SELECT 0 AS n UNION SELECT 10 UNION SELECT 20 UNION SELECT 30 UNION SELECT 40 UNION SELECT 50 UNION SELECT 60 UNION SELECT 70 UNION SELECT 80 UNION SELECT 90) AS n10 CROSS JOIN (SELECT 0 AS n UNION SELECT 100 UNION SELECT 200 UNION SELECT 300 UNION SELECT 400 UNION SELECT 500 UNION SELECT 600 UNION SELECT 700 UNION SELECT 800 UNION SELECT 900) AS n100 CROSS JOIN (SELECT 0 AS n UNION SELECT 1000 UNION SELECT 2000 UNION SELECT 3000) AS n1000 ) AS Sequence WHERE n BETWEEN 1 AND Len( @InitCap ) AND SubString( @InitCap, n, 1 ) LIKE '[az]' /* this character is a letter */ AND ( n = 1 /* this character is the first `character` */ OR SubString( @InitCap, n-1, 1 ) LIKE '[^az]' /* the previous character is NOT a letter */ ) AND ( n < 3 /* only test the 3rd or greater characters for this exception */ OR SubString( @InitCap, n-2, 3 ) NOT LIKE '[az]''[az]' /* exception: The pattern <letter>'<letter> should not capatolize the letter following the apostrophy */ ) -- 3. Return the modified version of the input RETURN @InitCap END 

保持对冯·诺依曼,麦凯恩,德古兹曼和约翰逊 – 史密斯的照顾的例外情况是有意义的。

我想你会发现以下更有效率:

 IF OBJECT_ID('dbo.ProperCase') IS NOT NULL DROP FUNCTION dbo.ProperCase GO CREATE FUNCTION dbo.PROPERCASE ( @str VARCHAR(8000)) RETURNS VARCHAR(8000) AS BEGIN SET @str = ' ' + @str SET @str = 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( @str, ' 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') RETURN RIGHT(@str, LEN(@str) - 1) END GO 

replace语句可以被剪切并直接粘贴到SQL查询中。 这是非常丑陋的,但是通过用您感兴趣的列replace@str,您将不会为隐式游标支付价格,就像您将发布的udfs一样。 我发现,即使使用我的UDF,它也更有效率。

哦,而不是手动生成replace语句使用这个:

 -- Code Generator for expression DECLARE @x INT, @c CHAR(1), @sql VARCHAR(8000) SET @x = 0 SET @sql = '@str' -- actual variable/column you want to replace WHILE @x < 26 BEGIN SET @c = CHAR(ASCII('a') + @x) SET @sql = 'REPLACE(' + @sql + ', '' ' + @c+ ''', '' ' + UPPER(@c) + ''')' SET @x = @x + 1 END PRINT @sql 

无论如何,这取决于行数。 我希望你可以做s / \ b([az])/ uc $ 1 /,但是我们可以使用我们拥有的工具。

注意,你将不得不使用这个,因为你将不得不使用它…. SELECT dbo.ProperCase(LOWER(column)),因为列是大写的。 它实际上在我的5000个条目(甚至不到一秒)的表格上工作得相当快,即使是较低的。

为了回应关于国际化的一系列评论,我提出了以下仅依靠SQL Server的上下文实现来处理每个ASCII字符的实现。 请记住,我们在这里使用的variables是VARCHAR,这意味着它们只能保存ASCII值。 为了使用更多国际字母,您必须使用NVARCHAR。 逻辑将是类似的,但您将需要使用UNICODE和NCHAR代替ASCII和CHAR,replace语句将更加巨大….

 -- Code Generator for expression DECLARE @x INT, @c CHAR(1), @sql VARCHAR(8000), @count INT SEt @x = 0 SET @count = 0 SET @sql = '@str' -- actual variable you want to replace WHILE @x < 256 BEGIN SET @c = CHAR(@x) -- Only generate replacement expression for characters where upper and lowercase differ IF @x = ASCII(LOWER(@c)) AND @x != ASCII(UPPER(@c)) BEGIN SET @sql = 'REPLACE(' + @sql + ', '' ' + @c+ ''', '' ' + UPPER(@c) + ''')' SET @count = @count + 1 END SET @x = @x + 1 END PRINT @sql PRINT 'Total characters substituted: ' + CONVERT(VARCHAR(255), @count) 

基本上我的方法的前提是交易预效率的计算。 完整的ASCII实现如下:

 IF OBJECT_ID('dbo.ProperCase') IS NOT NULL DROP FUNCTION dbo.ProperCase GO CREATE FUNCTION dbo.PROPERCASE ( @str VARCHAR(8000)) RETURNS VARCHAR(8000) AS BEGIN SET @str = ' ' + @str SET @str = 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(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(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(@str, ' 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'), ' š', ' Š'), ' œ', ' Œ'), ' ž', ' Ž'), ' à', ' À'), ' á', ' Á'), ' â', ' Â'), ' ã', ' Ã'), ' ä', ' Ä'), ' å', ' Å'), ' æ', ' Æ'), ' ç', ' Ç'), ' è', ' È'), ' é', ' É'), ' ê', ' Ê'), ' ë', ' Ë'), ' ì', ' Ì'), ' í', ' Í'), ' î', ' Î'), ' ï', ' Ï'), ' ð', ' Ð'), ' ñ', ' Ñ'), ' ò', ' Ò'), ' ó', ' Ó'), ' ô', ' Ô'), ' õ', ' Õ'), ' ö', ' Ö'), ' ø', ' Ø'), ' ù', ' Ù'), ' ú', ' Ú'), ' û', ' Û'), ' ü', ' Ü'), ' ý', ' Ý'), ' þ', ' Þ'), ' ÿ', ' Ÿ') RETURN RIGHT(@str, LEN(@str) - 1) END GO 

返回并获取非大写的数据为时已晚?

冯·诺依曼,麦凯恩,德古兹曼和你的客户群中的约翰逊 – 史密斯可能不喜欢你的处理结果。

另外,我猜这是为了一次性升级数据? 导出,过滤/修改和重新导入更正的名称到数据库可能会更容易,然后您可以使用非SQL方法来命名修复…

以下是我在SQLTeam.com Forums上find的另一个变体:http: //www.sqlteam.com/forums/topic.asp?TOPIC_ID=47718

 create FUNCTION PROPERCASE ( --The string to be converted to proper case @input varchar(8000) ) --This function returns the proper case string of varchar type RETURNS varchar(8000) AS BEGIN IF @input IS NULL BEGIN --Just return NULL if input string is NULL RETURN NULL END --Character variable declarations DECLARE @output varchar(8000) --Integer variable declarations DECLARE @ctr int, @len int, @found_at int --Constant declarations DECLARE @LOWER_CASE_a int, @LOWER_CASE_z int, @Delimiter char(3), @UPPER_CASE_A int, @UPPER_CASE_Z int --Variable/Constant initializations SET @ctr = 1 SET @len = LEN(@input) SET @output = '' SET @LOWER_CASE_a = 97 SET @LOWER_CASE_z = 122 SET @Delimiter = ' ,-' SET @UPPER_CASE_A = 65 SET @UPPER_CASE_Z = 90 WHILE @ctr <= @len BEGIN --This loop will take care of reccuring white spaces WHILE CHARINDEX(SUBSTRING(@input,@ctr,1), @Delimiter) > 0 BEGIN SET @output = @output + SUBSTRING(@input,@ctr,1) SET @ctr = @ctr + 1 END IF ASCII(SUBSTRING(@input,@ctr,1)) BETWEEN @LOWER_CASE_a AND @LOWER_CASE_z BEGIN --Converting the first character to upper case SET @output = @output + UPPER(SUBSTRING(@input,@ctr,1)) END ELSE BEGIN SET @output = @output + SUBSTRING(@input,@ctr,1) END SET @ctr = @ctr + 1 WHILE CHARINDEX(SUBSTRING(@input,@ctr,1), @Delimiter) = 0 AND (@ctr <= @len) BEGIN IF ASCII(SUBSTRING(@input,@ctr,1)) BETWEEN @UPPER_CASE_A AND @UPPER_CASE_Z BEGIN SET @output = @output + LOWER(SUBSTRING(@input,@ctr,1)) END ELSE BEGIN SET @output = @output + SUBSTRING(@input,@ctr,1) END SET @ctr = @ctr + 1 END END RETURN @output END GO SET QUOTED_IDENTIFIER OFF GO SET ANSI_NULLS ON GO