Честно говоря, Dynami c SQL - это, вероятно, путь к go, поскольку у вас есть универсальный запрос, но не ваши динамические c SQL. Это огромный риск инъекций. Параметризуйте операторы:
DECLARE @SQL nvarchar(MAX),
@CRLF nchar(2) = CHAR(13) + CHAR(10);
SET @SQL = N'SELECT *' + @CRLF +
N'FROM TableA A' + @CRLF +
CASE WHEN @PersonID IS NOT NULL THEN N'WHERE A.ID = @PersonID;'
WHEN @MhnNum IS NOT NULL THEN N'WHERE A.MhnNum = @MhnNum;'
END;
EXEC sys.sp_executesql @SQL, N'@PersonID int, @MhnNum int', @PersonID, @MhnNum;
Использование не динамического подхода c приведет к кешированию плохих планов запросов, что нежелательно.
Если вы должны использовать non Dynami c SQL (из-за бессмысленной Политики Компании, в Dynami c SQL, если используется правильно, нет ничего плохого), затем добавьте OPTION RECOMPILE
:
IF @PersonID IS NOT NULL AND @MhnNum IS NOT NULL
THROW 68542, N'Both @PersonID and @MhnNum cannot be non-NULL values.', 11;
SELECT *
FROM TableA A
WHERE (A.ID = @PersonID OR @PersonID IS NULL)
AND (A.MhnNum = @MhnNum OR @MhnNum IS NULL)
OPTION (RECOMPILE);
The THROW
там, так как ваш код также будет иметь ошибку, если у вас есть 2 не NULL
значения.