Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SQL Proper Case Function Query Refinement

Tags:

function

sql

I have a table of names that I am trying to convert from UPPERCASE to Proper Case. And the below code does almost exactly what I am. When I was testing it out I noticed that I had folks who had Roman Numerals in their name, Mc* and O'* in the table. Naturally the query converted any multiple Roman Numeral into Iv like it was supposed to and any MCDONALDS or O'DANIEL were converted into Mcdonalds and O'daniel. I was trying to figure out how to make a clean change to this function so I can run my update query but I'm still peacemilling my SQL knowledge together in off hours. Any help/suggestions would be much appreciated. I did a google search and found several examples but the ones I tried didn't work. The amount of corrections I would have to do is relatively minor (17 corrections out of 1000 row table), but I'd like to try and tidy it up to limit as many human errors as possible.

Thank you in advance for your help.

CREATE FUNCTION [dbo].[f_ProperCase]
(@Text as varchar(80))
RETURNS varchar(80) as
BEGIN

DECLARE @Reset bit
DECLARE @Ret varchar(80)
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 
CASE WHEN SUBSTRING(@Text,@i-4,5) like '_[a-z] [DOL]''' THEN 1 
WHEN SUBSTRING(@Text,@i-4,5) like '_[a-z] [D][I]' THEN 1 
WHEN SUBSTRING(@Text,@i-4,5) like '_[a-z] [M][C]' THEN 1 
WHEN SUBSTRING(@Text,@i-4,5) like '_[a-z] [M][c][*]' THEN 1 --Convert MCDONALD to     McDonald
WHEN SUBSTRING(@Text,@I-4,5) like '_[a-z] [O][''][*]' THEN 1 --Convert O'DONNEL to O'Donnel
ELSE 0 
END = 1 
THEN 1 
ELSE CASE WHEN @c like '[a-zA-Z]' or @c in ('''') THEN 0 
ELSE 1 
END 
END,
@i = @i +1
RETURN @Ret
end
like image 526
J. E. Flint Avatar asked Feb 13 '23 06:02

J. E. Flint


1 Answers

I would do it differently:

CREATE FUNCTION [dbo].[f_ProperCase]
(@Text as varchar(80))
RETURNS varchar(80) as
BEGIN

DECLARE @Reset bit
DECLARE @Ret varchar(80)
DECLARE @i int
DECLARE @c char(1)
DECLARE @Text1 varchar(81)

SELECT @Reset = 1, @i=1, @Ret = '', @Text1 = ' ' + @Text

WHILE @i <= LEN(@Text1)
    SELECT @c= SUBSTRING(@Text1,@i,1),
    @Ret = @Ret + CASE WHEN @Reset=1 THEN UPPER(@c) ELSE LOWER(@c) END,
    @Reset= CASE WHEN 
    CASE WHEN SUBSTRING(@Text1,@i-2,3) like ' [DdOoLl]''' THEN 1 
    WHEN SUBSTRING(@Text1,@i-2,4) like ' [Mm][cC][a-zA-Z]' THEN 1 
    WHEN SUBSTRING(@Text1,@i-3,5) like ' [Mm][Aa][cC][a-zA-Z]' THEN 1 
    ELSE 0 
    END = 1 
    THEN 1 
    ELSE CASE WHEN @c like '[a-zA-Z]' or @c in ('''') THEN 0 
    ELSE 1 
    END 
    END,
    @i = @i +1
RETURN stuff(@Ret, 1, 1, '')
end

This function supports O', L', D', as well as Mc, and Mac. The function is also converts from any case (not only the upper case) to the proper case

SQL Fiddle

select dbo.f_ProperCase('CORMACK')
      ,dbo.f_ProperCase('Mcdonald ronald')
      ,dbo.f_ProperCase('o''hara')

|         |                 |        |
|---------|-----------------|--------|
| Cormack | McDonald Ronald | O'Hara |
like image 67
cha Avatar answered Feb 19 '23 06:02

cha