Extract email address from string using tsql

后端 未结 6 1424
面向向阳花
面向向阳花 2021-01-13 09:01

I\'m trying to extract email addresses from an existing comments field and put it into its own column. The string may be something like this \"this is an example comment wit

6条回答
  •  野趣味
    野趣味 (楼主)
    2021-01-13 09:31

    Stephan's answer is great when looking for a single email address in each row.

    However, I was running into this error when trying to get multiple email addresses in each row:

    Invalid length parameter passed to the LEFT or SUBSTRING function

    I used this answer from DBA Stack Exchange to get all of the positions of @ inside the string. It entails a table-valued function that returns the number of positions equal to the number a certain pattern inside the string. I also had to modify the CROSS APPLY functions to handle multiple email addresses as well.

    My Table:

    DECLARE @Table TABLE (comment VARCHAR(500));
    INSERT INTO @Table (comment)
    VALUES ('blah blah My.EmailAddress@domain.org more blah someemailaddress@domain.com even more blah asdf@gmail.com'),
           ('blah hello.world@domain.org more'),
           ('no email')
    

    Table-valued Function:

    CREATE FUNCTION dbo.fnFindPatternLocation
    (
        @string NVARCHAR(MAX),
        @term   NVARCHAR(255)
    )
    RETURNS TABLE
    AS
        RETURN 
        (
            SELECT pos = Number - LEN(@term) 
            FROM (SELECT Number, Item = LTRIM(RTRIM(SUBSTRING(@string, Number, 
            CHARINDEX(@term, @string + @term, Number) - Number)))
            FROM (SELECT ROW_NUMBER() OVER (ORDER BY [object_id])
            FROM sys.all_objects) AS n(Number)
            WHERE Number > 1 AND Number <= CONVERT(INT, LEN(@string))
            AND SUBSTRING(@term + @string, Number, LEN(@term)) = @term
        ) AS y);
    GO
    

    Query:

    SELECT comment, pos, SUBSTRING(comment,beginningOfEmail,endOfEmail-beginningOfEmail) AS email
    FROM @Table
    CROSS APPLY (SELECT pos FROM dbo.fnFindPatternLocation(comment, '@')) AS A(pos)
    CROSS APPLY (SELECT CHARINDEX(' ',comment + ' ', pos)) AS B(endOfEmail)
    CROSS APPLY (SELECT pos - CHARINDEX(' ', REVERSE(SUBSTRING(comment, 1, pos))) + 2) AS C(beginningOfEmail)
    

    Results:

    comment
    ---------------------------------------------------------------------------------------------------------
    blah blah My.EmailAddress@domain.org more blah someemailaddress@domain.com even more blah asdf@gmail.com
    blah blah My.EmailAddress@domain.org more blah someemailaddress@domain.com even more blah asdf@gmail.com
    blah blah My.EmailAddress@domain.org more blah someemailaddress@domain.com even more blah asdf@gmail.com
    blah hello.world@domain.org more
    

    pos    email
    ---    ------------------------------
    26     My.EmailAddress@domain.org
    64     someemailaddress@domain.com
    95     asdf@gmail.com
    17     hello.world@domain.org
    

提交回复
热议问题