2010-06-25 48 views
0

我有一個SQL語句,在SQL語句中的SELECT列表可以使用正則表達式

select ColumnName from Table 

我得到這樣的結果,

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

所以無論如何領域有很多東西它,我只想擺脫'用戶名'。

我可以使用正則表達式嗎?

我的意思是這將是一種像這樣,

select SUBSTRING(ColumnName, 0, 5) from Table 

除SUBSTRING將與某種正則表達式來代替。我很喜歡正則表達式,但我不確定如何在這種情況下應用它,或者即使可以。

如果我能得到這個工作,這將是巨大的,因爲我打算將數據拉入臨時表,並做一些相當複雜的事情與其他表匹配它等。如果我能得到這一切工作,它會救我編寫一個C#應用程序來完成它。

謝謝。

+0

可能的[SQL Server內部正則表達式]的重複(http://stackoverflow.com/questions/1964124/regular-expression-inside-sql-server) – 2010-06-25 05:03:18

+0

有用閱讀: [tsql正則表達式工作臺](http://www.simple-talk.com/sql/t-sql-programming/tsql-regular-expression-workbench/) – 2010-06-29 12:51:33

回答

1

不,開箱即用,SQL Server不支持正則表達式。

您可以通過部署到SQL Server的SQL-CLR程序集來改造這些程序。

0

無論如何,我認爲你應該使用SUBSTRING。使用正則表達式更加靈活,但也會導致大量的處理開銷。如果您必須處理大型記錄集,這會變得更糟。

如果首先需要靈活性,您必須證明自己的合理性。

如果是的話,你應該在這裏讀到它:

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

使用T-SQL只可以看起來像:

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,使用子字符串/ charindex等,需要爲每個字符串編寫一個單獨的提取你想從你的字符串中獲得一段數據。用正則表達式,一種模式,你就完成了。更簡單的維護。正確的,可維護的和「慢」的跳動錯誤,混亂和「快速」的任何一天。 – MaasSql 2010-06-26 04:16:51

0

UPDATE

我們說不出哪裏 用戶名的開頭是。除非我們可以說「找到 我 第二空間後開始字符」

這是非常簡單的:

  • 過濾掉少於 兩個空格(或者字符串,有三個 或更多的話);
  • 查找第一個 空間後的位置(或者,第二個單詞的開頭 );
  • 找到第一個空格後的第一個空格 (或者,第三個字的起始 )之後的第一個空格後的位置;
  • 確定第三個字的長度使用 空間的位置(或字符串的末尾是 只有三個字)的位置;
  • 使用上述值與 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; 

原來的答案:

是對問題,即用戶名值的位置和/或長度可以不是在數據恆定的,但總是遵循字符串'用戶名'?如果是這樣,您可以使用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個字符長。此外,字符串'用戶名'將不在該字段中。它只是一個真正的用戶名'jerryb'或'georget'等。我得到的是我們無法知道用戶名的起始位置。除非我們可以說'在第二個空間之後找到我的起始角色'。那有意義嗎? – peter 2010-06-27 21:15:10

相關問題