将SQL列中的分隔值拆分为多行

我真的很喜欢这里的一些build议,给我一些背景信息,我正在从Exchange 2007插入邮件跟踪日志到SQL。 因为我们每天有数以百万计的行,所以我使用Bulk Insert语句将数据插入到SQL表中。

事实上,我实际上批​​量插入到一个临时表,然后从那里我把数据合并到活动表,这是为testingparsing问题,因为某些领域,否则引号和周围的价值观。

这很好,除了收件人地址列是由a分隔的分隔字段这一事实之外。 字符,有时可能会有很多电子邮件收件人。

我想采取这一列,并将值分成多行,然后将插入到另一个表。 问题是我想要的东西要么太长,要么就是不按我想要的方式工作。

以此示例数据为例:

message-id recipient-address 2D5E558D4B5A3D4F962DA5051EE364BE06CF37A3A5@Server.com user1@domain1.com E52F650C53A275488552FFD49F98E9A6BEA1262E@Server.com user2@domain2.com 4fd70c47.4d600e0a.0a7b.ffff87e1@Server.com user3@domain3.com;user4@domain4.com;user5@domain5.com 

我希望这个格式如下我的收件人表格中:

 message-id recipient-address 2D5E558D4B5A3D4F962DA5051EE364BE06CF37A3A5@Server.com user1@domain1.com E52F650C53A275488552FFD49F98E9A6BEA1262E@Server.com user2@domain2.com 4fd70c47.4d600e0a.0a7b.ffff87e1@Server.com user3@domain3.com 4fd70c47.4d600e0a.0a7b.ffff87e1@Server.com user4@domain4.com 4fd70c47.4d600e0a.0a7b.ffff87e1@Server.com user5@domain5.com 

有没有人有任何想法,我怎么能这样做呢?

我知道PowerShell相当好,所以我尝试过,但是即使在28Klogging上的foreach循环也需要永久处理,我需要尽可能快速/高效地运行。

谢谢!

首先,创build一个拆分函数:

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

现在你可以通过简单的推断:

 SELECT s.[message-id], f.Item FROM dbo.SourceData AS s CROSS APPLY dbo.SplitStrings(s.[recipient-address], ';'); 

另外我build议不要在列名中加上破折号。 这意味着你总是必须把它们放在[square brackets]

SQL Server 2016包含一个新的表函数string_split(),类似于以前的解决scheme。

唯一的要求是将兼容性级别设置为130(SQL Server 2016)