Share via


SQL Developers Toolbox – Splitter Function

Introduction

There are many case uses for splitter functions. Maybe you have old legacy data in your database which has multiple values stored in a single column. Perhaps you’re sanitizing data as it comes into your database. Either way, a good, robust and well performing split technique is a must for us all.

Demo Data

Let’s setup an example using some made up data.

DECLARE @table TABLE  (ID INT, delimitedValues VARCHAR(MAX))
INSERT INTO  @table  (ID, delimitedValues) VALUES
(1, '123,456,789,101112'),(2,'the quick brown fox, jumps, over the lazy, dog'),(3,'that''s, great, it, starts, with, an, earthquake')
 
SELECT *
  FROM @table

There we have it, three rows of data that’s delimited by commas.

Now we need a splitter function to pull it apart. I’m going to list my most up to date incarnation of my splitter function here. This one has not had as much testing done on it, but it should perform in much the same way as the previous one.

splitterMkII

CREATE FUNCTION  dbo.splitterMkII(@string VARCHAR(MAX), @delim VARCHAR(10))
RETURNS @result TABLE (id INT IDENTITY, value VARCHAR(MAX))
AS
BEGIN
 WHILE CHARINDEX(@delim,@string) > 0
  BEGIN
   INSERT INTO  @result (value) VALUES (LEFT(@string,CHARINDEX(@delim,@string)-1))
   SET @string = RIGHT(@string,LEN(@string)-(CHARINDEX(@delim,@string)+(LEN(@delim)-1)))
  END
   INSERT INTO  @result (value) VALUES (@string)
 
RETURN
END
GO

The difference between this one and the previous version is just the variable length delimiter. MkII allows for any length of delimiter, the previous only allowed for a single character. For reference purposes, here’s the old one.

Splitter

CREATE FUNCTION  dbo.splitter(@string VARCHAR(MAX), @delim CHAR(1))
RETURNS @result TABLE (id INT IDENTITY, value VARCHAR(MAX))
AS
BEGIN
 WHILE CHARINDEX(@delim,@string) > 0
  BEGIN
   INSERT INTO  @result (value) VALUES (LEFT(@string,CHARINDEX(@delim,@string)-1))
   SET @string = RIGHT(@string,LEN(@string)-CHARINDEX(@delim,@string))
  END
   INSERT INTO  @result (value) VALUES (@string)
 
RETURN
END
GO

Both functions accept a string (to MAX) and a delimiter to split that string by:

SELECT *
 FROM dbo.splitterMkII('string1======string2======string3','======')

They return a table of IDs and values. This allows you to select particular splits, should the need arise:

SELECT *
 FROM dbo.splitterMkII('string1======string2======string3','======')
 WHERE ID IN  (2,3)

Putting it to use

You can use the function with a pivot to turn those rows into columns

DECLARE @table TABLE  (ID INT, delimitedValues VARCHAR(MAX))
INSERT INTO  @table  (ID, delimitedValues) VALUES
(1, '123,456,789,101112'),(2,'the quick brown fox, jumps, over the lazy, dog'),(3,'that''s, great, it, starts, with, an, earthquake')
 
SELECT *
  FROM @table t
    CROSS APPLY dbo.splitterMkII(delimitedValues,',') s
    PIVOT (
           MAX(value) FOR  s.ID IN ([1],[2],[3],[4],[5],[6],[7],[8])
       ) p 

And there we have it. Delimited data into columns.