简体   繁体   中英

Select item from a string of items

I have a string of email recipients in the format like this:

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

"SELECT DISTIECT..." is a simple and powerful SQL statement, but it works against a table. Is there a simple way to select distinct recipient from the recipient list variable like FOR loop in C# or Ruby?

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

By the way, I am using TSQL in SQL server 2005.

Here's a solution for you that uses a temporary table.

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

The idea is to continously parse the email from the string, insert it into a temporary table, and remove the parsed email from the remaining string.

You can use loop through the temporary table afterward to send your individual emails.

eg

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

What you want in a Split function that will return a table for you to work with.

There are uncountable implementations around but I'm not aware of a built-in one, or a consensus of the 'best'.

I use a function like the one below to deal with a similar situation when receiving lists like that from the front end. Then you can just use this code to return the string as a table instead:

SELECT DISTINCT String FROM dbo.GetTableFromStringList(@recipients)

You probably want to do the actual sending of the email in something other than T-SQL code though.

Here's the function:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM