SQL Server 2008, различные предложения WHERE с одним запросом

У меня есть хранимая процедура, которая принимает те же столбцы, но с разнымиWHERE пункт.

Что-то вроде этого.

SELECT
     alarms.startt, alarms.endt, clients.code, clients.Plant,
     alarms.controller, alarmtype.atype, alarmstatus.[text]
FROM alarms
INNER JOIN clients ON alarms.clientid = clients.C_id 
INNER JOIN alarmstatus ON alarms.statusid = alarmstatus.AS_id
INNER JOIN alarmtype ON alarms.typeid = alarmtype.AT_id

и я помещаю тот же запрос в 3, если условия (условия), гдеWHERE Предложение изменяется в соответствии с параметром, переданным в переменной.

Должен ли я писать всю строку снова и снова для каждого условия в каждом if?

Или я могу оптимизировать его до одного раза, и единственное, что изменится, будет предложение WHERE?

 codingbiz20 июн. 2012 г., 18:57
где ваши настройки и параметры?
 Tab Alleman15 дек. 2015 г., 19:19
Вы должны выбрать один из ответов ниже, чтобы закрыть вопрос. Этот вопрос часто задают, и здесь можно указать дубликаторы.
 Andrew Savinykh21 июн. 2012 г., 00:04
Помечено для перехода на dba.stackexchange.com, так как это лучше подходит для вопроса.

Ответы на вопрос(6)

I would go this way: WHERE 8 = CASE @parameter WHEN 1 THEN Column1 WHEN 2 THEN Column2 . . .

 20 нояб. 2015 г., 19:28
Не могли бы вы разработать свое решение немного больше, пожалуйста? Как я понимаю вопрос, весь пункт WHERE может отличаться.

Вы не должны, вы можете обойти это, делая что-то вроде

SELECT  *
FROM    [Query]
WHERE   (@Parameter = 1 AND Column1 = 8)
OR      (@Parameter = 2 AND Column2 = 8)
OR      (@Parameter = 3 AND Column3 = 8)

Однако то, что вы можете что-то сделать, не означает, что вы должны это делать. Меньше многословного SQL не означает лучшую производительность, поэтому используйте что-то вроде:

IF @Parameter = 1
    BEGIN
        SELECT  *
        FROM    [Query]
        WHERE   Column1 = 8
    END
ELSE IF @Parameter = 2
    BEGIN
        SELECT  *
        FROM    [Query]
        WHERE   Column2 = 8
    END
ELSE IF @Parameter = 3
    BEGIN
        SELECT  *
        FROM    [Query]
        WHERE   Column3 = 8
    END

в то время как эквивалент первого запроса должен привести к лучшей производительности, поскольку он будет оптимизирован лучше.

 FedeSc20 июн. 2012 г., 19:02
если по опыту вы говорите, что это не «плохая практика» повторяя запросы, то я верю. это были и мои решения. я хотел знать, как к этому подходят старые таймеры, я немного новичок в SQL SERVER и привык в своем уме пытаться оптимизировать код настолько, насколько я могу, законный вопрос и спасибо вам обоим за ваши ответы , :)

Я бы, вероятно, придерживался повторения всего SQL-оператора, но прибегал к этому в прошлом ...

WHERE (@whichwhere=1 AND [email protected])
  OR (@whichwhere=2 AND [email protected])
  OR (@whichwhere=3 AND [email protected])

Не особенно читабельно, и вам придется проверять план выполнения, если он медленный, но он не дает вам повторить код.

Ну, как и большинство вещей в SQL: это зависит. Здесь есть несколько соображений.

Would the the different WHEREs lead to substantially different query plans for execution e.g. one of the columns indexed but not the other two Is the query likely to change over time: i.e. customer requirements needing other columns Is the WHERE likely to become 4, then 8, then 16 etc options.

Один из подходов состоит в том, чтобы выполнить разные процедуры во временную таблицу. У каждого процесса будет свой план запроса.

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

Третий подход - написать приложение, генерирующее SQL для каждого параметра, это может быть либо хранимый процесс, либо строка sql.

Затем получите набор данных и проведите тестовую разработку на основе этого (это верно для каждого подхода).

В конце концов, лучшее решение для обучения, вероятно, а) читать о SQL Kalen Delaney Inside SQL является признанным экспертом. б) проверить свои собственные решения против ваших собственных данных

Вы можете избежать повторения кода, если вы делаете что-то вроде:

WHERE (col1 = @var1 AND @var1 IS NOT NULL)
OR ...
OPTION RECOMPILE;

Вы также можете повлиять на это поведение с помощью параметра параметризации базы данных (простой или принудительный).

То, что избегает повторения кода и избегает неоптимальных планов из-за перехвата параметров, заключается в использовании динамического SQL:

DECLARE @sql NVARCHAR(MAX) = N'SELECT ...';
IF @var1 IS NOT NULL
  SET @sql = @sql + ' WHERE ...';

Это может работать лучше, если у вас есть настройки сервера & quot; оптимизировать для специальных запросов & quot; включен.

Так как никто не предложил это. Вы можете поместить исходный запрос в представление, а затем получить доступ к представлению с различными предложениями WHERE.

Чтобы повысить производительность, вы даже можете добавить индексы в представление, если знаете, какие столбцы будут обычно использоваться в предложении WHERE (см.http://msdn.microsoft.com/en-us/library/dd171921(v=sql.100).aspx).

Ваш ответ на вопрос