分割がそんなに悪い考えだと思う理由がわかりません。Numbers テーブルがあると仮定すると、比較的効率的なインライン TVF を作成し、それに対して結合できます。
CREATE FUNCTION dbo.SplitStrings_Numbers
(
@List NVARCHAR(MAX),
@Delimiter NVARCHAR(255)
)
RETURNS TABLE
WITH SCHEMABINDING
AS
RETURN
(
SELECT Item = SUBSTRING(@List, Number,
CHARINDEX(@Delimiter, @List + @Delimiter, Number) - Number)
FROM dbo.Numbers
WHERE Number <= CONVERT(INT, LEN(@List))
AND SUBSTRING(@Delimiter + @List, Number, LEN(@Delimiter)) = @Delimiter
);
GO
(CLR などの絶対的に最も効率的なアプローチについては、http://www.sqlperformance.com/2012/07/t-sql-queries/split-strings を参照してください)
今、あなたは言うことができます:
SELECT t.rpt_title
FROM dbo.table_name AS t
INNER JOIN dbo.SplitStrings_Numbers(@Input, '|') AS x
ON t.rpt_title LIKE '%' + x.Item + '%'
GROUP BY t.rpt_title;
もう 1 つのアイデアはfoo|bar|splunge
、最初のようにリストを使用するのではなく、TVP を使用することです。最初にテーブル タイプを作成します。
CREATE TYPE dbo.TitleMatches
(
Pattern NVARCHAR(64)
);
GO
次に、それを使用するストアド プロシージャ:
CREATE PROCEDURE dbo.Whatever
@matches dbo.TitleMatches READONLY
AS
BEGIN
SET NOCOUNT ON;
SELECT t.rpt_title
FROM dbo.table_name AS t
INNER JOIN @matches AS m
ON t.rpt_title LIKE '%' + m.Pattern + '%'
GROUP BY t.rpt_title;
END
GO
次に、DataTable を渡すか、潜在的な一致のリストを保持する構造体を渡すだけです。たとえば、C# では次のようになります。
DataTable DataTableName = new DataTable();
// ... populate data table here
SqlCommand cmd = new SqlCommand("dbo.Whatever", conn);
cmd.CommandType = CommandType.StoredProcedure;
SqlParameter tvp = cmd.Parameters.AddWithValue("@matches", DataTableName);
tvp.SqlDbType = SqlDbType.Structured;
// ... execute, consume results, etc.
(詳細はhttp://www.sqlperformance.com/2012/08/t-sql-queries/splitting-strings-now-with-less-t-sqlを参照)