2011-01-07 2 views
4

데이터베이스의 "이름"필드에서 데이터를 정리하고 해당 데이터를 이름, 중간 이름, & 성으로 분할하려고합니다. 현재 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를 사용 중입니다.)

+3

이것은 SQL이 아닌 응용 프로그램 코드에서보다 잘 처리되는 작업입니다. –

답변

1

스트레이트로 수행하기가 쉽지 않다고 생각하지 않습니다. SQL. 정규 표현식을 사용할 수 있지만 정규 표현식 기능을 제공하기 위해 자신 만의 CLR 함수를 작성해야합니다.

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 

... 그리고 다른 청소를 할 준비가되었습니다.

+0

제안 해 주셔서 감사합니다. 나는 임시 테이블을 사용하는 것이 가능하다고 생각하지만, 여러 번 코드를 작성해야만한다. 이름 필드의 내용이 동시에 여러 "규칙"을 트리거 할 수 있으므로 재귀 구현이 유리할 것으로 생각됩니다. –

관련 문제