Knowledge is power. We love to share it.

News related to Mono products, services and latest developments in our community.

Goran

Parsing a delimited string in SQL Server

09/20/2011
If you ever had the need to parse a delimited string in SQL Server, then you know that there is no in-built function that does that. The function I’m about to write about is particullary useful if you are passing a parameter that contains multiple string values (eg. passing a parameter from the client side to a report instance in Reporting services) and you want to use it as a filter for “IN” expression in SQL.

In the following example, we wil populate a simple table variable with a short list of people with their first name, last name and birth city. After that, we will write a query that will return only people that have a birth city that matches one of the cities we've passed in a parameter.

First, let’s create and populate a simple table with three columns:

DECLARE @PeopleTable TABLE
(
    FirstName varchar(20),
    LastName varchar(20),
    BirthCity varchar(20)
)
  
INSERT INTO @PeopleTable
    SELECT 'Lisa', 'Martin', 'Chicago'
    UNION
    SELECT 'Brad', 'Brown', 'Chicago'
    UNION
    SELECT 'Adrian', 'Wilson', 'Denver'
    UNION
    SELECT 'Adam', 'Clark', 'Denver'
    UNION
    SELECT 'Tim', 'Taylor', 'New York'
    UNION
    SELECT 'Steven', 'Campbell', 'New York'
    UNION
    SELECT 'Molly', 'Jones', 'Washington'
    UNION
    SELECT 'Stacy', 'Santiago', 'Washington'


Now, take a look at the data we inserted into the table:

SELECT * FROM @PeopleTable

FirstName LastName BirthCity
Adam Clark Denver
Adrian Wilson Denver
Brad Brown Chicago
Lisa Martin Chicago
Molly Jones Washington
Stacy Santiago Washington
Steven Campbell New York
Tim Taylor New York


For this example, let’s filter the data in the PeopleTable by people that were born in Chicago or Denver. Normally, you would write something like this:

SELECT *
FROM @PeopleTable
WHERE BirthCity IN ( 'Chicago','Denver')
ORDER BY FirstName

FirstName LastName BirthCity
Adam Clark Denver
Adrian Wilson Denver
Brad Brown Chicago
Lisa Martin Chicago


But we want to pass the list of cities as a parameter:

DECLARE @DelimitedStringParameter varchar(60)
SET @DelimitedStringParameter  = 'Chicago,Denver'


If we run the following query, it would return zero rows.
 
SELECT *
FROM @PeopleTable
WHERE BirthCity IN (@DelimitedStringParameter)


The solution to this problem is the following function:
 
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE FUNCTION [dbo].[ParseDelimitedString]
(
    @String nvarchar(max),
    @Delimiter nvarchar(1)
)
RETURNS 
@OutputTable TABLE
(
    ParsedString nvarchar (50)
)
AS
BEGIN
    DECLARE @DelimiterIndex int
    SET @DelimiterIndex = -1
  
    WHILE (LEN(@String) > 0)
    BEGIN
        SET @DelimiterIndex = CHARINDEX(@Delimiter, @String)
        IF (@DelimiterIndex = 0) AND (LEN(@String) > 0)
            BEGIN
                INSERT INTO @OutputTable VALUES (LTRIM(RTRIM(@String)))
                BREAK
            END
        IF (@DelimiterIndex > 1)
            BEGIN
                INSERT INTO @OutputTable VALUES (LTRIM(RTRIM(LEFT(@String, @DelimiterIndex - 1))))
                SET @String = RIGHT(@String, (LEN(@String) - @DelimiterIndex))
            END 
        ELSE SET @String = RIGHT(@String, (LEN(@String) - @DelimiterIndex))
    END
      
    RETURN
END


The usage of ParseDelimitedString function:
 
SELECT ParsedString AS City
FROM dbo.ParseDelimitedString (@DelimitedStringParameter , ',')

City
Chicago
Denver


Now, let’s filter the data from PeopleTable:
 
SELECT *
FROM @PeopleTable
WHERE
    BirthCity IN
    (
        SELECT ParsedString
        FROM dbo.ParseDelimitedString (@DelimitedStringParameter , ',')
    
ORDER BY
    FirstName

FirstName LastName BirthCity
Adam Clark Denver
Adrian Wilson Denver
Brad Brown Chicago
Lisa Martin Chicago


Alternatively, we can filter the data using an inner join:

SELECT p.*
FROM
    @PeopleTable p
    INNER JOIN
    (
        SELECT ParsedString
        FROM dbo.ParseDelimitedString (@DelimitedStringParameter , ','
    ) y ON p.BirthCity = y.ParsedString 
ORDER BY
    FirstName


Please keep in mind that if you are gong to be using this function in a query that fetches a large chunk of data, it is advisable to store the parsed data into a temporary table that will be used in a query, so ParseDelimitedString function gets executed only once.

Let’s create the table variable that will be used to store the values returned by ParseDelimitedString function:
 
DECLARE @ParsedStringTable TABLE
(
    BirthCity varchar(20)
)


The usage of ParseDelimitedString function:

INSERT INTO @ParsedStringTable
    SELECT ParsedString FROM dbo.ParseDelimitedString (@DelimitedStringParameter , ',')


Our queries now look like this:

SELECT *
FROM @PeopleTable
WHERE BirthCity IN ( SELECT BirthCity FROM @ParsedStringTable ) 
ORDER BY
    FirstName

And this:

SELECT p.*
FROM
    @PeopleTable p
    INNER JOIN ( SELECT BirthCity FROM @ParsedStringTable ) y ON p.BirthCity = y.BirthCity 
ORDER BY
    FirstName
Rated 3.29, 7 vote(s). 
Hi Goran,

I read this article ,very nice concept it useful me was very
thanku
cheers



thanks Goren,
i like it.
By Oks
Thank you, Goren!
It helped me too