Как избавиться от динамов c SQL (T- SQL) - PullRequest
0 голосов
/ 26 марта 2020

У меня есть хранимая процедура, которая использует Dynami c SQL. Моя компания недавно решила избавиться от динамического c кода.

Здесь я значительно упростила его, чтобы объяснить мою точку зрения; @PersonID и @MhnNum являются параметрами хранимой процедуры:

Declare @sql Varchar(max)

Set @sql="Select from tableA p"

If @PersonID Is Not Null
    Set @sql = @sql + ' Where  p.[ID] = ' + cast(@PersonID  as varchar(12))      

If @MhnNum Is Not Null
    Set @sql = @sql + ' Where p.[MhnNum] = ' + '''' + cast(@MhnNum  as varchar(12)) + ''''

Есть ли (простой) способ избавиться от этой динамики c SQL?

Right Теперь мое решение состоит в том, чтобы создать 2 If с повторяющимся кодом. Должен быть более элегантный способ сделать это.

Ответы [ 3 ]

4 голосов
/ 26 марта 2020

Честно говоря, 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 значения.

2 голосов
/ 26 марта 2020

Простая комбинация or и and может дать вам тот же результат:

Select *
From tableA
Where (@personId is null or id = @personId) 
And (@MhnNum is null or whnNum =@mhnNum)
1 голос
/ 26 марта 2020

(запись в комментарии будет беспорядком)

Вы можете проверить параметры и действовать соответственно. ie:

Select from tableA p
where  (@PersonID IS NULL or p.[ID] = @PersonID) and
 (@MhnNum  IS NULL or p.[MhnNum] = @MhnNum);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...