2014-05-07 121 views
2

我想将包含多个电子邮件地址数据的单个字符串拆分为三个变量。字符串用电子邮件标记电子邮件地址的开始/结束;字符。将SQL字符串拆分为多个字符串

的示例串是:

'[email protected];[email protected];[email protected]' 

我现在有这样做的代码如下:

DECLARE @Email VARCHAR(100), 
     @Email2 VARCHAR(100), 
     @Email3 VARCHAR(100) 

SET @Email = '[email protected];[email protected];[email protected]' 

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) 

可惜,这似乎并没有工作。有人能指出我哪里出错了,我该怎么办才能解决我的问题?

在此先感谢。

+1

总是只有3个电子邮件地址吗? – MarkD

+0

可能的重复[如何分割字符串,以便我可以访问项目x](http://stackoverflow.com/questions/2647/how-do-i-split-a-string-so-i-can-access -item-x) – podiluska

回答

5

假设总是会有3个电子邮件地址 - 以下似乎工作;

DECLARE @Email VARCHAR(100), 
     @Email2 VARCHAR(100), 
     @Email3 VARCHAR(100) 

SET @Email = '[email protected];[email protected];[email protected]' 

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) 
+0

+1,他们的关键点是你正在使用可选的第三个参数,'CHARINDEX'用于在给定点后查找字符串中字符的位置以找到第二个分号(它总是很棒给你的答案添加一点解释,而不是仅仅给出代码) – GarethD

+0

好点GarethD,谢谢 – MarkD

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('[email protected];[email protected];[email protected]',';') 
1

尝试使用XML节点来拆分和分析字符串。代码示例如下:

declare @Email as varchar(100), @del as varchar(10), @xml as xml; 
set @Email='[email protected];[email protected];[email protected]'; 
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); 
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 

How do I split a string so I can access item x

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('[email protected];[email protected];[email protected]', ';'); 

...你最终得到一个充满电子邮件地址的临时表,我是他们的输入顺序。

0

最好的办法是将分隔字符串转换为柱状形式并从那里开始工作。

可以使用迭代法,或使用the Numbers table(我喜欢)的方法:

declare 
    @list varchar(1000), 
    @sep char(1) 

set @list = '[email protected];[email protected];[email protected]'; 
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 
相关问题