У меня есть отчет в SSRS 2005, основанный на запросе, похожем на этот:
SELECT * FROM MyTable (NOLOCK)
WHERE col1 = 'ABC'
AND col2 LIKE '%XYZ%'
Мне нужно иметь возможность динамически включать часть AND предложения WHERE в запрос в зависимости от того, установил ли пользователь флажок. По сути, это динамический оператор SQL, и в этом проблема. Я пробовал несколько подходов, но безрезультатно. Это возможно? Поддерживает ли SSRS 2005 динамический SQL? Спасибо!





Возможно, это сработает для вас:
if @checked = 1
select * from mytable (nolock) where col = 'ABC'
else
select * from mytable (nolock) where col = 'ABC' AND colw Like '%XYZ%'
Извините, я не очень часто использую SSRS, но если вы можете получить значение флажка в параметре @checked, это должно сработать.
В качестве альтернативы вы можете использовать оператор CASE WHEN.
Вы также можете выбрать другой подход и использовать функцию Exec:
DECLARE @CommonSelectText varchar(2000)
DECLARE @CompleteSelectText varchar(2000)
SELECT @CommonSelectText = 'SELECT * FROM MyTable (nolock) Where Col = ''ABC'' '
IF @checked = 1
SELECT @CompleteSelectText = @CommonSelectText + ' AND ColW LIKE ''%XYZ%'' '
ELSE
SELECT @CompleteSelectText = @CommonSelectText
EXEC (@CompleteSelectText)
GO
Обратите внимание на использование двух апострофов ' для обозначения цитируемого текста.
Как насчет этого. @checked - ваша битовая переменная.
SELECT * FROM MyTable (NOLOCK)
WHERE col1 = 'ABC'
AND (@checked <> 0 and col2 LIKE '%XYZ%')
Редактировать: Также, если вы не используете сохраненную процедуру, используйте ее.
Ваш ответ великолепен, но в случае, когда мы не можем выполнить на источнике данных и у нас есть доступ только для чтения к данным, подход с хранимой процедурой не будет работать.
Это не работает в случае, если check - false (0). В этом случае он не вернет никаких совпадений, даже если некоторые из них могут существовать.
SELECT * FROM MyTable (NOLOCK)
WHERE col1 = 'ABC'
AND col2 LIKE CASE @checked WHEN 1 THEN '%XYZ%' ELSE col2 END
Это будет работать в SSRS 2000, но используется в крайнем случае.
(плохо) ПСЕВДОКОД
= "SELECT * FROM MyTable (NOLOCK)
WHERE col1 = 'ABC'"+
iff(condition,true,"AND col2 LIKE '%XYZ%'","")
Проверьте Выполнение «динамических» SQL-запросов. из "Автостопом" по службам отчетов SQL Server 2000
Один из способов сделать это - создать запрос SSRS в виде выражения. В дизайнере отчетов BIDS настройте свой запрос следующим образом:
= "SELECT * FROM MyTable WITH (NOLOCK) WHERE col1 = 'ABC'" +
Iif (Parameters!Checked.Value = true," AND col2 LIKE '%XYZ%'","")
Чарльз почти правильно ответил.
Должен быть:
SELECT * FROM MyTable (NOLOCK)
WHERE col1 = 'ABC'
AND (@checked = 0 OR col2 LIKE '%XYZ%')
Это классический «шаблон» в SQL для условных предикатов. Если @checked = 0, то он вернет все строки, соответствующие остатку от предиката (col1 = 'ABC'). SQL Server даже не обработает вторую половину OR.
Если @checked = 1, то он оценит вторую часть OR и вернет строки, соответствующие col1 = 'ABC' AND col2 LIKE '%XYZ%'.
Если у вас есть несколько условных предикатов, их можно связать вместе с помощью этого метода (тогда как методы IF и CASE быстро станут неуправляемыми).
Например:
SELECT * FROM MyTable (NOLOCK)
WHERE col1 = 'ABC'
AND (@checked1 = 0 OR col2 LIKE '%XYZ%')
AND (@checked2 = 0 OR col3 LIKE '%MNO%')
Не используйте динамический SQL, не используйте IF или CASE.
Да, я терпеть не могу динамический SQL, который невероятно сложно отлаживать, поддерживать или обновлять. Некоторые незначительные улучшения производительности, если у вас есть большое количество необязательных параметров, но даже с 30 параметрами я получил хорошую производительность, не прибегая к ней.
Не говоря уже о том, насколько это опасно с точки зрения безопасности.
Отличный ответ
если вы можете использовать хранимые процедуры, вероятно, это проще сделать там. передать свои параметры. Создайте строку SQL на основе ваших условий и выполните EXEC для строки sql, ваша сохраненная процедура вернет вам нужные результаты.
Ваш ответ великолепен, но в случае, когда мы не можем выполнить на источнике данных и у нас есть доступ только для чтения к данным, подход с хранимой процедурой не будет работать.
В SQL Server это может вызвать перекомпиляцию плана запроса, что может снизить производительность. Если вы используете этот шаблон в своих собственных процедурах, подумайте о разделении, чтобы у вас была главная процедура, которая выбирает, какую дочернюю процедуру вызывать на основе параметров - одна процедура один запрос.