1

对于 SQL Server 2005 实例,查找/替换包含多个电子邮件的列的最佳方法是什么

<JimmyTheBoot@yahoo.com>; JohnBlaze@TestMail.com; comfarmer@yahoo.com .....

并将其替换为

<TestMail@yRandMail.com>; TestMail@RandMail.com; TestMail@RandMail.com .....

出于测试目的,我可以想出一些在 C# 中执行此操作的方法,但我想知道是否有在 SQL Server 中执行此操作的思考方法,也许使用 REGEX ?我想尽可能地保持随机的怪异(有些电子邮件有括号,有些邮件末尾有分号等......)

谢谢

4

2 回答 2

2

在这里,您可以使用函数中的 cte 来完成它。

create function dbo.FixupEmails(@s varchar(8000))
returns table
as
return (
      WITH splitter_cte AS (
      SELECT CHARINDEX(';', @s) as pos, 0 as lastPos, 1 as cte_level
      UNION ALL
      SELECT CHARINDEX(';', @s, pos + 1), pos, cte_level + 1 as cte_level
      FROM splitter_cte
      WHERE pos > 0
      ), each_email_cte AS(
      select replace(replace(replace(OneEmail, '>', ''), '<', ''), ' ', '') as OneEmail, cte_level
        from (select SUBSTRING(@s, lastPos + 1,
                         case when pos = 0 then 80000 else pos - lastPos -1 end) as OneEmail,
                         cte_level
                from splitter_cte) as t
      ), each_half_cte AS (
        select OneEmail, CHARINDEX('@', OneEmail) as atPos, cte_level
        from each_email_cte
        where len(OneEmail) > 6  -- 6 from x@x.co (I think that 6 would be the minimum valid email length)
      ), new_email_cte as
      (
        select cte1.OneEmail, Replace(@s, cte1.OneEmail, 'TestMail@RandMail.com') as New, cte1.cte_level --, 1 as level
        from each_half_cte cte1
        where cte1.cte_level = 1

        UNION ALL

        select cte2.OneEmail, Replace(necte.New, cte2.OneEmail, 'TestMail@RandMail.com') as New, cte2.cte_level--, 1 as level
        from new_email_cte as necte
        inner join each_half_cte as cte2 on cte2.cte_level = necte.cte_level + 1


      )
      select New
      from new_email_cte
      where cte_level = (select max(cte_level) from new_email_cte)
)
go

set nocount on;

declare @emailString varchar(2048)
set @emailString = '<JimmyTheBoot@yahoo.com>; JohnBlaze@TestMail.com; comfarmer@yahoo.com ';
select @emailString as Original;
SELECT *
  FROM dbo.FixupEmails(@emailString);




set @emailString = '<JimmyTheBoot@yahoo.com>; JohnBlaze@TestMail.com;';
select @emailString as Original;
SELECT *
  FROM dbo.FixupEmails(@emailString);


set @emailString = '<JimmyTheBoot@yahoo.com>';
select @emailString as Original;
SELECT *
  FROM dbo.FixupEmails(@emailString)
OPTION(MAXRECURSION 0);
-- include MAXRECURSION as shown above if you have more than 100 email addresses in the field.



set @emailString = '<bill@whatever.co.uk>; John@TestMail.tv;';
select @emailString as Original;
SELECT *
  FROM dbo.FixupEmails(@emailString)

它有点长,但这是输出。

Original
----------------------------------------------------------------
<JimmyTheBoot@yahoo.com>; JohnBlaze@TestMail.com; comfarmer@yahoo.com 

New
-----------------------------------------------------------------
<TestMail@RandMail.com>; TestMail@RandMail.com; TestMail@RandMail.com 




Original
----------------------------------------------------------------
<JimmyTheBoot@yahoo.com>; JohnBlaze@TestMail.com;

New
----------------------------------------------------------------
<TestMail@RandMail.com>; TestMail@RandMail.com;





Original
----------------------------------------------------------------
<JimmyTheBoot@yahoo.com>

New
----------------------------------------------------------------
<TestMail@RandMail.com>





Original
----------------------------------------------------------------
<bill@whatever.co.uk>; John@TestMail.tv;

New
----------------------------------------------------------------
<TestMail@RandMail.com>; TestMail@RandMail.com;

这很有趣。我认为提供的功能将满足您的需求。

于 2012-04-20T02:02:32.297 回答
1

几个建议:

  • SQL Server 字符串函数

    一种方法可能是:

    1. 查找@符号的索引
    2. 用您的电子邮件 ID 替换它之前的部分(直到前一个空格或其他字符 - 可能是 set [],;<>())
    3. 用您的域替换它之后的部分(直到下一个空格或其他字符)
    4. 与列中的下一个 @ 符号重复

    如果您碰巧替换了友好名称的一部分而不是电子邮件标识符,那么它应该不重要。

    使用 CHARINDEX 查找字符串中 @ 符号的下一个索引。使用 PATINDEX 查找特定模式的索引,例如空格或其他分隔符。将字符串按部分分块或在空白处拆分可能比一次处理整个事情更容易。

  • 编写一个正则表达式并设置一个 SQL CLR 函数来进行替换也可能更容易。

  • 如果替换电子邮件地址的原因是避免向他们发送电子邮件,您可以在应用程序中设置调试标志/选项。设置标志后,将电子邮件地址替换为开发人员定义的地址或日志,但忽略电子邮件发送。

于 2012-04-20T01:45:29.120 回答