Or, you can go simple... Assuming that the parameters are passed in through a VARCHAR variable called @Parameters... SELECT * FROM yourtable WHERE ','+somecolumn+',' LIKE '%,'+@Parameters+',%'
Now, for some reason, people tend to stay away from such simplicity... perhaps it's the bloody TABLE SCAN it causes
... but it does only take 3 seconds on a million row table.So... with performance in mind, you could do something like this (I have a test table called "BigTest" with a million rows in it). This little dity returns the 5,112 found rows from the million row table in 216 MILLI-SECONDS. Here's the code without a split function...DECLARE @Parameters VARCHAR(8000) SET @Parameters = ',AA,BB,CC,,EE,'-- SET @Parameters = ','+@Parameters+',' SELECT * FROM dbo.BigTest bt, (--Derived table "d" contains the split parameters SELECT SUBSTRING(@Parameters,N+1,CHARINDEX(',', @Parameters, N+1) - N-1) AS Value FROM dbo.Tally WHERE N < LEN(@Parameters) AND SUBSTRING(@Parameters,N,1) = ',' ) d WHERE bt.SomeValue = d.Value
Notice that the parameter was passed in with leading and trailing commas. If your GUI doesn't do that, just uncomment the line in the code above that adds them... Also notice that there's no special handling required to skip unused parameters and there's no requirement to include single quotes. Kinda handy and your GUI guys should love you...Ok, you probably also noticed the TALLY table thingy... all it is is a table with a single column of numbers and it has a great many uses not the least of which is the elimination of cursors and while loops for such things as "split" functions.... Every database should have one (or make it part of MASTER)... here's how to make one...--===== Create and populate the Tally table on the fly SELECT TOP 11000 --equates to more than 30 years of dates when needed IDENTITY(INT,1,1) AS N INTO dbo.Tally FROM Master.dbo.SysColumns sc1, Master.dbo.SysColumns sc2--===== Add a Primary Key to maximize performance ALTER TABLE dbo.Tally ADD CONSTRAINT PK_Tally_N PRIMARY KEY CLUSTERED (N)--===== Allow the general public to use it GRANT SELECT ON dbo.Tally TO PUBLIC
Finally, if you absolutely must have a function do this for you (and you should in this case), the function would look like this (REAL simple with a Tally table)... CREATE FUNCTION dbo.udfSplit(@Parameters VARCHAR(7998))RETURNS @MyReturn TABLE (Value VARCHAR(7998)) AS BEGIN --===== Conditionally "Groom" @Parameters to contain a leading and trailing comma IF LEFT(@Parameters,1) <> ',' SET @Parameters = ','+@Parameters IF LEFT(@Parameters,1) <> ',' SET @Parameters = @Parameters+',' --===== Split the parameters into the return table INSERT INTO @MyReturn (Value) SELECT SUBSTRING(@Parameters, N+1, CHARINDEX(',', @Parameters, N+1) - N-1) AS Value FROM dbo.Tally WHERE N < LEN(@Parameters) AND SUBSTRING(@Parameters,N,1) = ',' RETURN END
... and the previous example would now look like this...DECLARE @Parameters VARCHAR(8000) SET @Parameters = ',AA,BB,CC,,EE,' SELECT * FROM dbo.BigTest bt, dbo.udfSplit(@Parameters) d WHERE bt.SomeValue = d.Value
... and it still only takes about 216 MILLI-SECONDS.Lemme know if this helps, eh?--Jeff Modenp.s. Special thanks to Adam Mechanic for turning me on to Tally tables several years back.