如何递归在SQL语句
我试图清理数据在我们的数据库中的“名称”字段和分割解析数据这些数据转化为姓,中间名,姓氏&。目前,我使用Case
语句在文本内查找各种触发器,以帮助我以某种方式格式化输出。如何递归在SQL语句
不过,我开始注意到,我中嵌套等检查测试和需要弄清楚如何处理递归数据。看到我如何抽取名字的这个例子。
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)
我不认为这是一些容易/清洁直SQL
完成。您可以使用正则表达式,但是您必须编写自己的CLR
函数来提供正则表达式功能。
这听起来像是一次性活动。你确定你在使用临时表的几个语句中不能这么做吗?如果这是一次性活动,那么您可能比代码性能更需要准确性和简单的代码调试。
考虑这样的事情:
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
...你准备做另一个横扫。
感谢您的建议。我想使用临时表是一种可能性,但它迫使我多次编写代码。由于名称字段的内容可能同时触发多个“规则”,因此在我看来,递归实现将是有利的。 – 2011-01-08 16:05:13
这是一个在应用程序代码而不是SQL中更好处理的任务。 – 2011-01-07 19:21:40