2011-01-30 5 views
3

예 : 다음 표 데이터 :SQL Server의 단일 행에서 여러 문자열을 추출하는 방법

id | text 
-------------------------------------------------------------------------------- 
1  | Peter ([email protected]) and Marta ([email protected]) are doing fine. 
2  | Nothing special here 
3  | Another email address ([email protected]) 

지금 내 텍스트 열에서 (단지 괄호를 확인하기 위해 그 좋아) 모든 이메일 주소를 반환하는 선택을해야하고, 여러가있는 경우 그 이상의 행을 반환 텍스트 컬럼의 주소. 나는 how to extract the first element을 알고 있지만, 두 번째 이상의 결과를 찾는 방법에 대해서는 전혀 모릅니다.

+2

데이터에 불균형 괄호가 전혀 없다고 가정 할 수 있습니까? –

+0

예. 나중에 오류를 해결할 수는 있지만 여기에서 작업 예제가 필요합니다. 현실 세계에서 문제가되는 이메일 주소가 아닙니다. 문제를 설명하고 작은 예를 만드는 것입니다. – Daniel

답변

5

cte를 재귀 적으로 사용하여 문자열을 제거 할 수 있습니다.

declare @T table (id int, [text] nvarchar(max)) 

insert into @T values (1, 'Peter ([email protected]) and Marta ([email protected]) are doing fine.') 
insert into @T values (2, 'Nothing special here') 
insert into @T values (3, 'Another email address ([email protected])') 

;with cte([text], email) 
as 
(
    select 
     right([text], len([text]) - charindex(')', [text], 0)), 
     substring([text], charindex('(', [text], 0) + 1, charindex(')', [text], 0) - charindex('(', [text], 0) - 1) 
    from @T 
    where charindex('(', [text], 0) > 0 
    union all 
    select 
     right([text], len([text]) - charindex(')', [text], 0)), 
     substring([text], charindex('(', [text], 0) + 1, charindex(')', [text], 0) - charindex('(', [text], 0) - 1) 
    from cte 
    where charindex('(', [text], 0) > 0 
) 
select email 
from cte 

결과

이가 더 불량 괄호가없는 당신이 당신의 텍스트가 어떤 XML 엔티티 문자를 포함 할 수있는 경우에 몇 가지 추가 replace의를 추가해야 가정
email 
[email protected] 
[email protected] 
[email protected] 
-1

하위 문자열 함수의 시작 위치 매개 변수가 있습니다. 따라서 첫 번째 발생을 찾고 발생 위치 + occurenceLength에서 다음 검색을 시작합니다 (루프에서). 값을 구분 된 문자열 또는 테이블로 반환하는 함수를 작성해야합니다. @ -sign을 사용하여 전자 메일 주소로가는 길을 찾은 다음 전자 메일 주소 (또는 시작 위치 또는 시작 문자 또는 마지막 문자)에서 유효하지 않은 공백이나 문자에 도달 할 때까지 앞뒤로 스캔합니다.

+0

MSSQL에 LOOP가 있습니까? 난 그냥 SQL 인터페이스를 가지고 ... – Daniel

+0

@ 대니얼. 당신은 UDF를 작성해야합니다. – Tim

+0

왜 downvote ????? T-SQL에서 함수를 작성할 수 있습니다. – Tim

2

.

WITH basedata(id, [text]) 
    AS (SELECT 1, 'Peter ([email protected]) and Marta ([email protected]) are doing fine.' 
     UNION ALL 
     SELECT 2, 'Nothing special here' 
     UNION ALL 
     SELECT 3, 'Another email address ([email protected])'), 
    cte(id, t, x) 
    AS (SELECT *, 
       CAST('<foo>' + REPLACE(REPLACE([text],'(','<bar>'),')','</bar>') + '</foo>' AS XML) 
     FROM basedata) 
SELECT id, 
     a.value('.', 'nvarchar(max)') as address 
FROM cte 
     CROSS APPLY x.nodes('//foo/bar') as addresses(a) 
관련 문제