Могу ли я объединить условие if с извлечением хранимой процедуры? - PullRequest
0 голосов
/ 22 мая 2018

Я разрабатываю хранимую процедуру, которая должна принимать некоторые параметры.Один из этих параметров говорит мне, сколько записей я должен взять, но если его значение равно 0 или меньше, тогда он должен извлечь все строки.Я разработал следующее решение, которое мне не нравится:

IF (@take > 0) BEGIN
    SELECT
          *
    FROM Properties
        -- Some conditions and joins are here using other parameters
        -- A big Order by with cases is placed here
    OFFSET @skip ROWS
    FETCH NEXT @take ROWS ONLY;
END
ELSE BEGIN
            SELECT
          *
    FROM Properties
        -- Some conditions and joins are here using other parameters
        -- A big Order by with cases is placed here
    OFFSET @skip ROWS;
END;

Проблема с вышеприведенным условием состоит в том, что я должен убедиться, что SQL-выражения совпадают, за исключением последней строки внутри условия if.Один из подходов, которые я также попробовал, состоял в том, чтобы создать строку запроса и выполнить ее, используя EXEC, но одна из переменных будет исходить непосредственно от пользователя, и поэтому я уязвим для внедрения SQL.

Мне также нужно будет улучшить приведенный выше код, чтобы ИП мог получать параметр, указывающий, следует ли ему «группировать по» по некоторому полю, что заставит меня добавить еще одну ветвь в каждое из этих условий (поэтомувышеуказанное решение не очень масштабируемое).Есть ли лучший подход?

1 Ответ

0 голосов
/ 22 мая 2018

Вы можете использовать выражение CASE вместо прямой переменной @take:

SELECT
      *
FROM Properties
    -- Some conditions and joins are here using other parameters
    -- A big Order by with cases is placed here
OFFSET @skip ROWS
FETCH NEXT CASE WHEN @take > 0 THEN @take ELSE 1000001 END ROWS ONLY;

Конечно, для этого нужно выбрать «достаточно большую» константу для ELSEэто больше, чем любой разумный набор результатов, который вы ожидаете, что ваш запрос вернет.Обычно я выбираю округленное число и добавляю его, имея в виду, что я буду отображать результаты с «круглым числом», и если я получу этот дополнительный результат, я могу хотя бы включить индикатор того, что запрос дал еще больше результатов, чем этот.

Это основано на предположении, что пользователь контролирует фильтрацию, и вы хотите / можете сказать: «Вы знаете, что результатов слишком много. Используйте функцию подкачки, если вы действительно хотите работатьчерез все из них, но я не буду пытаться показать их все вам сейчас ".


Мне также придется улучшить приведенный выше код, чтобы позволить SP получать параметруказание, должно ли оно «группироваться по» некоторому полю

Это более хитрое предложение.Запрос с предложением GROUP BY обязательно влечет за собой предложение SELECT, которое содержит столбцы, охватываемые предложением GROUP BY или агрегатными выражениями .(а если нет агрегатов, какой смысл в группировке?).Это принципиально отличается от запроса, не относящегося к группировке, поэтому вы не можете переключаться между ними с помощью простого переключателя / флага.

В этот момент запросы вряд ли будут иметь большое сходство (за исключением, возможно, FROM предложение о том, что вы, возможно, захотите перейти в представление или табличную функцию для повторного использования) или вам потребуется переключиться на динамический SQL.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...