Обычно вы делаете это, используя динамический SQL , так как кодирование условий динамического поиска с использованием статического SQL обычно хакерское. Если вас интересует такой подход, я настоятельно рекомендую страницу Эрланда Соммарскога по динамическому SQL для SQL Server 2005 . У него есть отличный пример с большим количеством примеров кода о том, как сделать именно то, что вы просите.
1. Настройка
Используете ли вы динамический или статический SQL, вы должны предварительно определить, какие фильтры применяются:
DECLARE @p1_filter BIT;
DECLARE @p2_filter BIT;
SET @p1_filter = 0;
SET @p2_filter = 0;
IF EXISTS (SELECT TOP (1) * FROM Parameters1)
BEGIN
SET @p1_filter = 1;
END;
IF EXISTS (SELECT TOP (1) * FROM Parameters2)
BEGIN
SET @p2_filter = 1;
END;
2.а. Динамический SQL
Если вы идете по динамическому маршруту SQL, вы должны сделать:
DECLARE @sql NVARCHAR(MAX);
SET @sql = 'SELECT * FROM Tran T ';
IF (@p1_filter = 1)
BEGIN
SET @sql = @sql + 'INNER JOIN Parameters1 p1 ON T.code1 = p1.code1 ';
END;
IF (@p2_filter = 1)
BEGIN
SET @sql = @sql + 'INNER JOIN Parameters2 p2 ON T.code2 = p2.code2 ';
END;
EXECUTE sp_executesql
@statement = @sql
;
2.b.i. Статический SQL: подвыборы в предложении WHERE
В противном случае вы бы продолжили использовать этот уродливый (и, вероятно, плохо работающий) статический SQL:
SELECT *
FROM Tran T
WHERE
(
T.code1 IN (SELECT code1 FROM Parameters1)
OR (@p1_filter = 0)
)
AND
(
T.code2 IN (SELECT code2 FROM Parameters2)
OR (@p2_filter = 0)
)
;
Эрланд также представляет статические SQL-подходы, подобные этому, на на той же странице , о которой я говорил ранее. Вы можете найти лучший подход там.
2.b.ii. Статический SQL: LEFT OUTER JOIN
Вы также можете использовать этот подход, который вы предложили в комментариях к этому ответу:
SELECT *
FROM
Tran T
LEFT OUTER JOIN Parameters1 p1
ON T.code1 = p1.code1
LEFT OUTER JOIN Parameters2 p2
ON T.code2 = p2.code2
WHERE
T.code1 =
CASE
WHEN @p1_filter = 1
THEN p1.code1
ELSE T.code1
END
AND T.code2 =
CASE
WHEN @p2_filter = 1
THEN p2.code2
ELSE T.code2
END
;