Tuesday, April 28, 2009

Splitting Strings in T-SQL

[EDIT] A very good collection of solutions:

From an ex-colleague (with some alteration):

Create Procedure ReturnStringAsTable
(
@REQUEST VARCHAR(500),
@dividingChr VARCHAR(1) = ','
)
AS
BEGIN
DECLARE @CURRENT_TABLE VARCHAR(200);
DECLARE @INDEX_TO INT;
DECLARE @INDEX_FROM INT;

DEClARE @DATASETINDEX TABLE(ID INT IDENTITY(1,1),[NAME] VARCHAR(200))

SET @INDEX_FROM=0;

SET @INDEX_TO= CHARINDEX(@dividingChr,@REQUEST,@INDEX_FROM);
SET @INDEX_TO= CASE WHEN @INDEX_TO <=0 THEN LEN(@REQUEST)+1 ELSE @INDEX_TO end;

WHILE @INDEX_FROM <>
BEGIN

SET @CURRENT_TABLE=RTRIM(LTRIM(SUBSTRING(@REQUEST,@INDEX_FROM,@INDEX_TO-@INDEX_FROM)))
IF LEN(@CURRENT_TABLE)>2
BEGIN
INSERT INTO @DATASETINDEX([NAME]) VALUES(@CURRENT_TABLE);
EXEC ('SELECT * FROM ' + @CURRENT_TABLE)
END

SET @INDEX_FROM = @INDEX_TO+1

SET @INDEX_TO= CHARINDEX(',',@REQUEST,@INDEX_FROM);
SET @INDEX_TO = CASE WHEN @INDEX_TO > @INDEX_FROM THEN @INDEX_TO ELSE LEN(@REQUEST)+1 END;
END

INSERT INTO @DATASETINDEX([NAME]) VALUES('INDEX_TABLE');

SELECT * FROM @DATASETINDEX
END




CREATE FUNCTION Split(
@IDValues as varchar(500),
@Delimeter as varchar(1)
)

RETURNS @tValues TABLE(IDAux INT)

AS

BEGIN

DECLARE @I AS INT, @Aux AS INT
SET @I = 1
SET @Aux = 1

WHILE @I <= LEN(@IDValues)

BEGIN
IF SUBSTRING(@IDValues,@I,1)= @Delimeter
BEGIN
INSERT INTO @tValues (IDAux) VALUES (CAST(SUBSTRING(@IDValues,@Aux,(@I-@Aux))AS INT))

SET @Aux = @i + 1
END

SET @i = @i + 1
END

RETURN

END

GO

--examples with differents delimeters

select * from Split('1058,1059,1060,1062,',',')
select * from Split('1058|1059|1060|1062|','|')
select * from Split('1058;1059;1060;1062;',';')

No comments:

Post a Comment