从一串项目中选择项目

时间:2009-03-18 13:26:40

标签: sql sql-server-2005 tsql

我有一串电子邮件收件人,格式如下:

 DECLARE @recipients VARCHAR(MAX);
 ....
 PRINT @recipients;
 /* the result
 person1@yahoo.com;person2@hotmail.com;person1@yahoo.com;...
 */

“SELECT DISTIECT ...”是一个简单而强大的SQL语句,但它适用于表。是否有一种简单的方法可以从收件人列表变量中选择 distinct 收件人,例如C#或Ruby中的FOR循环?

 FOR @recipient IN @recipients
 BEGIN
    -- send email to @recipient
 END

顺便说一句,我在SQL Server 2005中使用TSQL。

4 个答案:

答案 0 :(得分:2)

以下是使用临时表的解决方案。

declare @emails varchar(2000)
set @emails = 'person1@yahoo.com;person2@hotmail.com;person1@yahoo.com;'

declare @results table (row int identity(1,1), email varchar(500))

while ((select charindex(';',@emails)) > 0)
begin   
    insert into @results select substring(@emails,1,charindex(';',@emails))
    select @emails = substring(@emails,charindex(';',@emails)+1,len(@emails))
end

select distinct email from @results

我们的想法是不断解析字符串中的电子邮件,将其插入临时表中,然后从剩余的字符串中删除已解析的电子邮件。

您可以在之后使用临时表循环发送个人电子邮件。

答案 1 :(得分:1)

e.g。

CREATE FUNCTION dbo.Split (@sep char(1), @s varchar(512))
RETURNS table
AS
RETURN (
    WITH Pieces(pn, start, stop) AS (
      SELECT 1, 1, CHARINDEX(@sep, @s)
      UNION ALL
      SELECT pn + 1, stop + 1, CHARINDEX(@sep, @s, stop + 1)
      FROM Pieces
      WHERE stop > 0
    )
    SELECT pn,
      SUBSTRING(@s, start, CASE WHEN stop > 0 THEN stop-start ELSE 512 END) AS s
    FROM Pieces
  )
GO

答案 2 :(得分:0)

您希望在Split函数中返回一个表格供您使用。

有无数的实现around,但我不知道内置的实现,或者是'最佳'的共识。

答案 3 :(得分:0)

我使用类似下面的函数来处理类似的情况,从前端接收类似的列表。然后你可以使用这段代码将字符串作为表返回:

SELECT DISTINCT String FROM dbo.GetTableFromStringList(@recipients)

您可能希望以不同于T-SQL代码的方式实际发送电子邮件。

这是功能:

CREATE FUNCTION [dbo].[GetTableFromStringList]
(
    @StringList VARCHAR(1000),
    @Delimiter  CHAR(1) = ','
)
RETURNS @Results TABLE
(
    String  VARCHAR(1000)   NOT NULL
)
AS
BEGIN
    DECLARE
        @string     VARCHAR(1000),
        @position   SMALLINT

    SET @StringList = LTRIM(RTRIM(@StringList)) + @Delimiter
    SET @position = CHARINDEX(@Delimiter, @StringList)

    WHILE (@position > 0)
    BEGIN
        SET @string = LTRIM(RTRIM(LEFT(@StringList, @position - 1)))

        IF (@string <> '')
        BEGIN
            INSERT INTO @Results (String) VALUES (@string)
        END

        SET @StringList = RIGHT(@StringList, LEN(@StringList) - @position)
        SET @position = CHARINDEX(@Delimiter, @StringList, 1)
    END

    RETURN
END