Вы можете сделать это с помощью OR
:
WHERE (@Id > 0 AND Table1.Field = @Id)
OR (@Id = 0 AND Table1.Field IN (6,16,18))
Однако я бы посоветовал использовать (как вы сказали) IF/ELSE
, при смене двух условий, подобных этому, вы часто можете заставить субоптимальные планы. например В вашем примере вы могли бы упростить это к схеме следующим образом:
CREATE TABLE T
( ID INT IDENTITY(1, 1) NOT NULL PRIMARY KEY,
Field INT NOT NULL,
SomeOtherField INT NULL
);
GO
INSERT T (Field)
SELECT Number
FROM Master..spt_values
CROSS JOIN (VALUES (1), (2), (3)) t (A)
WHERE Type = 'P'
GO
CREATE NONCLUSTERED INDEX IX_T_Field ON T (Field) INCLUDE (SomeOtherField);
Это просто заполнит один из столбцов с номерами 0-2047 повторяется 4 раза каждый (только для некоторых, например, данные). Тогда Если я создаю две процедуры, одна из которых использует «IF/ELSE» один, который сочетает в себе критерии, как указано выше:
CREATE PROCEDURE dbo.Test @ID INT
AS
SELECT ID, Field, SomeOtherField
FROM T
WHERE (@Id > 0 AND T.Field = @Id)
OR (@Id = 0 AND T.Field IN (6,16,18))
GO
CREATE PROCEDURE dbo.Test2 @ID INT
AS
IF @ID = 0
SELECT ID, Field, SomeOtherField
FROM T
WHERE T.Field IN (6, 16, 18)
ELSE
SELECT ID, Field, SomeOtherField
FROM T
WHERE T.Field = @Id
GO
Поскольку составление запросов будет происходить только один раз (если явно не оговорено противное), Оптимизатор не будет выбрать другой план в зависимости от передать ли 0 или передать идентификатор> 0 в порядке, так как в следующем:
EXECUTE dbo.Test 0;
EXECUTE dbo.Test 1;
даст этот план:
Вторая процедура способна оценить лучший план выполнения гораздо лучше, так что работает так:
EXECUTE dbo.Test2 0;
EXECUTE dbo.Test2 1;
дает следующий план:
реальные примеры, очевидно, будет меняться, и у меня есть преднамеренно построил пример, который доказывает мою точку зрения. Это немного больше усилий, чтобы дублировать много кода, используя IF/ELSE
, но это часто стоит того.
Отлично, это прекрасно работает. Я не могу использовать 'if-else', в этом случае этот основной запрос уже работает inder' if-else'. Поэтому, если мне нужно использовать 'if-else', большая часть кода будет дублироваться. –
Это действительно хороший пример. Я сравню план затрат на основе моего дела. благодаря –