我正在尝试将包含多个电子邮件地址数据的单个字符串拆分为三个变量。字符串标记电子邮件地址的开头/结尾;字符。
示例字符串为:
'joebloggs@gmailcom;jimbowen@aol.com;dannybaker@msn.com'
我目前的代码如下:
DECLARE @Email VARCHAR(100),
@Email2 VARCHAR(100),
@Email3 VARCHAR(100)
SET @Email = 'joebloggs@gmailcom;jimbowen@aol.com;dannybaker@msn.com'
SET @Email2 = SUBSTRING(@Email, CHARINDEX(';', @Email)+1, LEN(@Email))
SET @Email3 = SUBSTRING(@Email, CHARINDEX(';', @Email)+1, LEN(@Email))
SET @Email = SUBSTRING(@Email, 1, CHARINDEX(';', @Email)-1)
不幸的是,这似乎不起作用。有人可以指出我哪里出错了,我应该怎么做才能解决我的问题?
提前致谢。
答案 0 :(得分:5)
假设总会有3个电子邮件地址 - 以下似乎有效;
DECLARE @Email VARCHAR(100),
@Email2 VARCHAR(100),
@Email3 VARCHAR(100)
SET @Email = 'joebloggs@gmailcom;jimbowen@aol.com;dannybaker@msn.com'
SELECT @Email = LEFT(@Email, CHARINDEX(';', @Email) - 1)
,@Email2 = SUBSTRING (
@Email,
CHARINDEX(';', @Email) + 1,
CHARINDEX(';', @Email, CHARINDEX(';', @Email) + 1) - LEN(LEFT(@Email, CHARINDEX(';', @Email) )) - 1
)
,@Email3 = RIGHT(@Email, CHARINDEX(';', @Email)-1)
答案 1 :(得分:2)
此解决方案:
create function dbo.SplitString
(
@str nvarchar(max),
@separator char(1)
)
returns table
AS
return (
with tokens(p, a, b) AS (
select
cast(1 as bigint),
cast(1 as bigint),
charindex(@separator, @str)
union all
select
p + 1,
b + 1,
charindex(@separator, @str, b + 1)
from tokens
where b > 0
)
select
p-1 ItemIndex,
substring(
@str,
a,
case when b > 0 then b-a ELSE LEN(@str) end)
AS Item
from tokens
);
GO
答案 2 :(得分:2)
在SQL Server 2016中,您可以使用built-in STRING_SPLIT function。
SELECT value FROM STRING_SPLIT(@var, ';')
答案 3 :(得分:1)
尝试使用XML节点拆分和解析字符串。代码示例如下:
declare @Email as varchar(100), @del as varchar(10), @xml as xml;
set @Email='joebloggs@gmailcom;jimbowen@aol.com;dannybaker@msn.com';
set @del =';';
set @xml = '<root><c>' + replace(@Email,@del,'</c><c>') + '</c></root>';
select email.value('.','varchar(100)') as Email
from @xml.nodes('//root/c') as records(email);
答案 4 :(得分:0)
这里的作品我很久以前就遇到了它。不能为工作带来任何好评,但这将完美无缺。
CREATE FUNCTION [dbo].[fnSplitString]
(
@string NVARCHAR(MAX),
@delimiter CHAR(1)
)
RETURNS @output TABLE(splitdata NVARCHAR(MAX)
)
BEGIN
DECLARE @start INT, @end INT
SELECT @start = 1, @end = CHARINDEX(@delimiter, @string)
WHILE @start < LEN(@string) + 1 BEGIN
IF @end = 0
SET @end = LEN(@string) + 1
INSERT INTO @output (splitdata)
VALUES(SUBSTRING(@string, @start, @end - @start))
SET @start = @end + 1
SET @end = CHARINDEX(@delimiter, @string, @start)
END
RETURN
END
select *from dbo.fnSplitString('joebloggs@gmailcom;jimbowen@aol.com;dannybaker@msn.com',';')
答案 5 :(得分:0)
我写了这个我定期使用的功能......
CREATE FUNCTION func_split(@value VARCHAR(8000), @delim CHAR)
RETURNS
@outtable TABLE (
i INTEGER,
value VARCHAR(1024)
)
AS
BEGIN
DECLARE @pos INTEGER
DECLARE @count INTEGER
IF LEN(@value) > 0
BEGIN
SET @count = 1
SET @value = @value + @delim
SET @pos = CHARINDEX(@delim, @value, 1)
WHILE @pos > 0
BEGIN
INSERT INTO @outtable (i, value) VALUES (@count, LEFT(@value, @pos - 1))
SET @value = RIGHT(@value, LEN(@value) - @pos)
SET @pos = CHARINDEX(@delim, @value, 1)
SET @count = @count + 1
END
END
RETURN
END
然后你用...来调用它。
DECLARE @emails AS TABLE (
i INTEGER,
value VARCHAR(1024)
)
INSERT INTO @split SEELCT * FROM func_split('joebloggs@gmailcom;jimbowen@aol.com;dannybaker@msn.com', ';');
...你最终会得到一个充满电子邮件地址的临时表,我是他们的输入订单。
答案 6 :(得分:0)
最好的办法是将分隔的字符串转换为柱状,然后从那里开始工作。
您可以使用迭代方法或使用the Numbers table的方法(我更喜欢):
declare
@list varchar(1000),
@sep char(1)
set @list = 'joebloggs@gmailcom;jimbowen@aol.com;dannybaker@msn.com';
set @sep = ';'
-- iterative method
declare @res table (
c varchar(100)
)
declare
@pos_start int,
@pos_end int,
@len_sep int,
@exit int
select @pos_start = 1, @pos_end = 1, @len_sep = len(@sep), @exit = 0
while @exit = 0
begin
set @pos_end = charindex(@sep, @list, @pos_start)
if @pos_end <= 0 begin
set @pos_end = len(@list) + 1
set @exit = 1
end
insert @res(c) select substring(@list, @pos_start, @pos_end - @pos_start)
set @pos_start = @pos_end + @len_sep
end
select * from @res
-- the Numbers table method
select substring(@list, n, charindex(@sep, @list + @sep, n) - n)
from numbers
where substring(@sep + @list, n, 1) = @sep
and n < len(@list) + 1