Firstly, I'd avoid storing delimited data in the database. As you've found out it can make database queries etc awkward.
If you have a limit amount of categories, I'd go with Joe's answer for simplicity, else, adding some detail to Marc's approach.
- Create a split-style UDF, for SQL Server I use:
CREATE FUNCTION FN_CHARLIST_TO_TABLE
(@list nvarchar(MAX),
@delimiter nchar(1) = N',')
RETURNS @tbl TABLE (listpos int IDENTITY(1, 1) NOT NULL,
str varchar(4000) NOT NULL,
nstr nvarchar(2000) NOT NULL) AS
/*
Comments:
- Takes a CSV string, and creates a table of data from this
- Each item takes one row in the following format
listpos - the index of the item in the string (effectively a row number in the output)
str - The value, as VARCHAR
nstr - The value, as NVARCHAR
- This function is a direct extract from http://www.sommarskog.se/arrays-in-sql-2005.html#iter-list-of-strings
Usage:
SELECT *
FROM t
JOIN FN_CHARLIST_TO_TABLE('a,b,c,1,2,3', ',') list
ON t.Name = list.str
*/
BEGIN
DECLARE @endpos int,
@startpos int,
@textpos int,
@chunklen smallint,
@tmpstr nvarchar(4000),
@leftover nvarchar(4000),
@tmpval nvarchar(4000)
SET @textpos = 1
SET @leftover = ''
WHILE @textpos 0
BEGIN
SET @tmpval = ltrim(rtrim(substring(@tmpstr, @startpos + 1,
@endpos - @startpos - 1)))
INSERT @tbl (str, nstr) VALUES(@tmpval, @tmpval)
SET @startpos = @endpos
SET @endpos = charindex(@delimiter COLLATE Slovenian_BIN2,
@tmpstr, @startpos + 1)
END
SET @leftover = right(@tmpstr, datalength(@tmpstr) / 2 - @startpos)
END
INSERT @tbl(str, nstr)
VALUES (ltrim(rtrim(@leftover)), ltrim(rtrim(@leftover)))
RETURN
END
- Add this to your DBML file
- Query your database, referencing the UDF appropriately
var catergories = from cat in _datacontext.Categories
from keyword in _datacontext.FN_CHARLIST_TO_TABLE(cat.Keywords, ' ')
where keyword.str == context.Request.QueryString["q"]
select cat;
This will then execute a purely database-side query.