2010-06-25 3 views
0

정규 표현식,는 SQL 문에서 선택 목록이 나는 SQL 문이

select ColumnName from Table 

를 사용할 수 그리고이 결과를 얻을,

Error 192.168.1.67 UserName 0bce6c62-1efb-416d-bce5-71c3c8247b75 An existing .... 

어쨌든 분야는 많은 재료에있다 그것, 나는 단지 'UserName'을 꺼내고 싶다.

정규식을 사용할 수 있습니까?

나는 문자열을 제외하고

select SUBSTRING(ColumnName, 0, 5) from Table 

은 어떤 종류의 정규 표현식으로 대체 될 것입니다, 그것은 종류의이 같은 것을 의미한다. 나는 정규식에 익숙하지만,이 경우에는 그것을 적용하는 방법이나, 할 수 있다고하더라도 확신 할 수 없다.

임시 테이블에 데이터를 가져오고 다른 테이블과 일치하는 복잡한 작업을 수행하기 때문에이 작업이 효과적 일 수 있습니다.이 작업을 모두 수행 할 수 있다면 나에게 도움이 될 것입니다. 그것을하기 위해 C# 응용 프로그램을 작성합니다.

감사합니다.

+0

가능한 [SQL Server 내 정규 표현식] (http://stackoverflow.com/questions/1964124/regular-expression-inside-sql-server) –

+0

유용합니다. 읽기 : [tsql 정규식 워크 벤치] (http://www.simple-talk.com/sql/t-sql-programming/tsql-regular-expression-workbench/) –

답변

1

SQL Server는 정규식을 지원하지 않습니다.

SQL Server에 배포하는 SQL-CLR 어셈블리를 사용하여 추가 할 수 있습니다.

0

어쨌든 SUBSTRING을 사용해야한다고 생각합니다. 정규 표현식을 사용하면보다 유연하지만 큰 처리 오버 헤드가 발생할 수도 있습니다. 큰 레코드 세트를 처리해야하는 경우 더욱 그렇습니다.

처음부터 유연성이 필요하면 정당화해야합니다.

당신은 여기에 대해 읽어야 그렇다면 : T-SQL을 사용하여

http://msdn.microsoft.com/en-us/magazine/cc163473.aspx

아니라 같이 할 수

SELECT 'Error 192.168.1.67 XUserNameX 0bce6c62-1efb-416d-bce5-71c3c8247b75 An existing' expr 
    INTO log_table 
GO 
WITH 
    split1 (expr, cstart, cend) 
AS (
     SELECT 
      expr, 1, 0 
     FROM 
      log_table a 
), split2 (expr, cstart, cend, div) 
AS (
    SELECT 
     a.expr, a.cend + 1, CHARINDEX(' ', a.expr, a.cend + 1), 1 
    FROM 
     split1 a 
    UNION ALL 
    SELECT 
     a.expr, a.cend + 1, CHARINDEX(' ', a.expr, a.cend + 1), div+1 
    FROM 
     split2 a 
    WHERE 
     a.cend > 1 
), substrings(expr, div) 
AS (
    SELECT 
     SUBSTRING(expr, cstart, cend - cstart), div 
    FROM 
     split2 
) 
SELECT expr from 
    substrings a 
where 
    a.div = 3 
+1

한 번 전적으로 동일한 대답을했을 것입니다. 그러나, 지금, 나는 확실히 말할 수 있습니다 - 정규식. 나는 나 자신을 너무 많이 정당화하려고 노력하지 않을 것이다. 나는 T-SQL의 문자열 조작 도구가 많이 남아 있다고 말하고, C#과 정규 표현식의 구현은 훌륭하다고 말하고, T-SQL에서는 substring/charindex 등을 사용하여 각각에 대해 별도의 추출을 작성해야한다. 문자열에서 원하는 데이터 조각. Regex를 사용하면 하나의 패턴이 완성됩니다. 유지 보수가 훨씬 간단합니다. 옳고, 유지 보수가 가능하며 "느린"박동은 언제나 잘못되어, 혼란스럽고 & 빠릅니다. – MaasSql

0

UPDATE

우리는 어디 말할 수 없다 사용자 이름의 시작은입니다.우리는 매우 간단

' 나에게 제 2 공간 후에 시작 문자 찾기'말할 수없는 한 :

  • 양자 택일 (미만 이 공백이 문자열을 필터링 세 이 또는 더 많은 단어들);
  • 첫 번째 공백 다음에 위치를 찾습니다 (또는 두 번째 단어의 시작 부분에 ).
  • 첫 번째 공백 후 공백 뒤에 위치를 찾으십시오 ( (또는 세 번째 단어의 시작 부분).
  • 다음 공백의 위치를 ​​사용하여 세 번째 단어의 길이를 결정하십시오 (또는 문자열의 끝은 이며 세 단어 만 있습니다).
  • 위의 값을 SUBSTRING() 함수와 함께 사용하면 세 번째 단어를 반환 할 수 있습니다.

예 :

WITH MyTable (ColumnName) 
AS 
(
SELECT NULL 
UNION ALL 
SELECT '' 
UNION ALL 
SELECT 'One.' 
UNION ALL 
SELECT 'Two words.' 
UNION ALL 
SELECT 'Three word sentence.' 
UNION ALL 
SELECT 'Sentence containing four words.' 
UNION ALL 
SELECT 'Five words in this sentence.' 
UNION ALL 
SELECT 'Sentence containing more than five words.' 
), 
AtLeastThreeWords (ColumnName, pos_word_2_start) 
AS 
(
SELECT M1.ColumnName, CHARINDEX(' ', M1.ColumnName) + LEN(' ') + 1 
    FROM MyTable AS M1 
    WHERE LEN(M1.ColumnName) - LEN(REPLACE(M1.ColumnName, ' ', '')) >= 2 
), 
MyTable2 (ColumnName, pos_word_3_start) 
AS 
(
SELECT M1.ColumnName, 
     CHARINDEX(' ', M1.ColumnName, pos_word_2_start) + LEN(' ') + 1 
    FROM AtLeastThreeWords AS M1 
), 
MyTable3 (ColumnName, pos_word_3_start, pos_word_3_end) 
AS 
(
SELECT M1.ColumnName, M1.pos_word_3_start, 
     CHARINDEX(' ', M1.ColumnName, pos_word_3_start) + LEN(' ') 
    FROM MyTable2 AS M1   
), 
MyTable4 (ColumnName, pos_word_3_start, word_3_length) 
AS 
(
SELECT M1.ColumnName, M1.pos_word_3_start, 
     CASE 
      WHEN pos_word_3_start < pos_word_3_end 
       THEN pos_word_3_end - pos_word_3_start 
      ELSE LEN(M1.ColumnName) - pos_word_3_start + 1 
     END   
    FROM MyTable3 AS M1   
) 
SELECT M1.ColumnName, 
     SUBSTRING(M1.ColumnName, pos_word_3_start, word_3_length) 
      AS word_3 
    FROM MyTable4 AS M1; 

ORIGINAL ANSWER :

항상 자명 값의 위치 및/또는 길이의 데이터가 일정하지 않을 수 있다는 문제가 있지만,이 다음에 string 'username'? 그렇다면 CHARINDEXSUBSTRING을 같이 사용할 수 있습니다.

WITH MyTable (ColumnName) 
AS 
(
SELECT 'Error 192.168.1.67 UserName 0bce6c62-1efb-416d-bce5-71c3c8247b75 An existing ....' 
UNION ALL 
SELECT 'Username onedaywhen is invalid' 

), 
MyTable1 (ColumnName, pos1) 
AS 
(
SELECT M1.ColumnName, CHARINDEX('UserName ', M1.ColumnName) + LEN('UserName ') + 1 
    FROM MyTable AS M1 
), 
MyTable2 (ColumnName, pos1, pos2) 
AS 
(
SELECT M1.ColumnName, M1.pos1, 
     CHARINDEX(' ', M1.ColumnName, pos1) - M1.pos1 
    FROM MyTable1 AS M1 
) 
SELECT SUBSTRING(M1.ColumnName, M1.pos1, M1.pos2) 
    FROM MyTable2 AS M1; 

... 예를 들어 더욱 강력하게 만들 필요가 있습니다. 사용자 이름 값 뒤에 후행 공백이 없을 때

+0

IP 주소는 어떤 값이든 가능합니다. 나는. 위의 IP 주소 192.168.1.89는 12 자이고 10.5.4.3은 8 자입니다. 또한 'Username'문자열은 필드에 없습니다. 그것은 단지 실제 사용자 이름 'jerryb'또는 'georget'등입니다. 내가 얻는 것은 사용자 이름의 시작 위치를 알 수 없다는 것입니다. '제 2의 공간 다음에 시작 캐릭터를 찾아주세요'라고 말할 수 없다면 말입니다. 말이 돼? – peter