SQL语句中的“选择”列表是否可以使用正则表达式

时间:2010-06-25 04:55:07

标签: sql sql-server

我有一个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

除了SUBSTRING将替换为某种正则表达式。我对正则表达式很满意,但我不确定如何应用它,或者即使你可以。

如果我能够实现这一点,那将会很棒,因为我计划将数据拉入一个临时表,并做一些与其他表匹配的相当复杂的事情。如果我能把这一切都搞定,那将节省我的写作一个C#应用程序来完成它。

感谢。

3 个答案:

答案 0 :(得分:1)

不,开箱即用,SQL Server不支持正则表达式。

您可以通过部署到SQL Server的SQL-CLR程序集来改进它们。

答案 1 :(得分: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

答案 2 :(得分:0)

更新

  我们无法分辨开始的地方   用户名是。除非我们能说'找到   我之后的起始人物   第二个空间'

这很简单:

  • 过滤掉少于的字符串 两个空格(或者,有三个 或更多的话);
  • 在第一个之后找到位置 空间(或者,开头 第二个字);
  • 找到第一个之后的位置 第一个空间后的空间 (或者,开头的 第三个字);
  • 确定第三个的长度 使用下一个位置的单词 空格(或字符串的结尾是 只有三个字);
  • 使用上述值 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;

原始回答:

问题是用户名值的位置和/或长度在数据中可能不是一成不变的,但总是跟在字符串'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;

...虽然你需要让它更健壮,例如当用户名值等后没有尾随空格时