I'm trying to clean up data in a "Name" field in our database and split that data into FirstName, MiddleName, & LastName. Currently, I'm using a Case
statement to look for various triggers inside the text to help me format the output in a certain way.
However, I'm starting to notice that I'm nesting tests inside other tests and need to figure out how to process data recursively. See this example of how I'm extracting the FirstName.
Case
When CharIndex(' ',LTrim(RTrim(Name))) in (0,1) Then '' --'empty or LName'
When Left(Name,3) IN ('MR ','MS ', 'DR ','MRS') Then --'Prefix Titles'
Case --'If we found a prefix, run the same "tests" with the prefix removed'
When CharIndex(' ',LTrim(RTrim(Right(Name,Len(Name)-CharIndex(' ',Name)))))
in (0,1) Then ''
When SubString(LTrim(RTrim(Right(Name,Len(Name)-CharIndex(' ',Name)))),3,1)
= '&' Then SubString(LTrim(RTrim(Right(Name,Len(Name)-CharIndex(' ',
Name)))),1,5)
Else Left(LTrim(RTrim(Right(Name,Len(Name)-CharIndex(' ',Name)))),
CHarIndex(' ',LTrim(RTrim(Right(Name,Len(Name)-CharIndex(' ',Name)))))-1)
End
When SubString(LTrim(RTrim(Name)),3,1) = '&' Then
SubString(LTrim(RTrim(Name)),1,5) --'Look for initials e.g. J & A Smith'
Else Left(LTrim(RTrim(Name)),CHarIndex(' ',LTrim(RTrim(Name)))-1)
End
So, in order to get this to work in more complicated situations (e.g. MR JOHN A SMITH JR
), I would need to test recursively. In imperative programming, I would do something like this if I had a function called GetFirstName
:
GetFirstName('MR JOHN A SMITH JR')
//GetFirstName identfies 'MR' and within the function it calls:
||
\\
==> GetFirstName('JOHN A SMITH JR')
//GetFirstName identifies 'JR' and within the function it calls:
||
\\
==> GetFirstName('JOHN A SMITH')
//Finally, it returns 'JOHN'
Ideally, it would be great to do this in straight SQL, but I'm not sure that is possible. What alternatives would I have if I'm not using straight SQL? (I'm using SQL Server 2005)