我正在尝试清理数据库中“名称”字段中的数据,并将该数据拆分为FirstName,MiddleName和&姓。目前,我正在使用Case
语句在文本中查找各种触发器,以帮助我以某种方式格式化输出。
但是,我开始注意到我在其他测试中嵌套测试,需要弄清楚如何递归处理数据。请参阅此示例,了解我如何提取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
因此,为了让它在更复杂的情况下工作(例如MR JOHN A SMITH JR
),我需要递归测试。在命令式编程中,如果我有一个名为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'
理想情况下,在直接SQL中执行此操作会很棒,但我不确定是否可行。如果我不使用直接SQL,我会有哪些替代方案? (我正在使用SQL Server 2005)
答案 0 :(得分:1)
我不认为直接SQL
可以轻松/干净地完成任务。您可以使用正则表达式,但是您必须编写自己的CLR
函数来提供正则表达式功能。
答案 1 :(得分:0)
这听起来像是一次性活动。您确定在使用临时表的几个语句中不能这样做吗?如果它是一次性活动,那么对代码调试的准确性和简单性的要求可能高于性能。
考虑这样的事情:
CREATE TABLE #MyNames ( PersonID INT PRIMARY KEY, OriginalName VARCHAR(50), WorkingName VARCHAR(50), CandidateTitle VARCHAR(10), CandidateLastName VARCHAR(50), CandidateFirstName VARCHAR(50), CandidateMiddleName VARCHAR(50) --Your other candidate fields..... ) INSERT INTO #MyNames (PersonID, OriginalName) SELECT TOP 100 ID, LTRIM(RTRIM(Name)) from SourcePersonTable --Possibly add some indexes here for original name UPDATE #MyNames SET CandidateTitle = LEFT(OriginalName,3), WorkingName = SUBSTRING(OriginalName,4,9999) Where LEFT(OriginalName,3) IN ('MR ','MRS','MS ','DR ') -- etc...
继续添加步骤并编辑[WorkingName]字段。当你完成一次传球时,就这样做......
UPDATE #MyNames SET WorkingName = OriginalName
......你已经准备好再做一次扫描。