SSRS: динамическое изменение инструкции SQL

У меня есть отчет в SSRS 2005, основанный на запросе, похожем на этот:

SELECT * FROM MyTable (NOLOCK) 
WHERE col1 = 'ABC'
AND col2 LIKE '%XYZ%'

Мне нужно иметь возможность динамически включать часть AND предложения WHERE в запрос в зависимости от того, установил ли пользователь флажок. По сути, это динамический оператор SQL, и в этом проблема. Я пробовал несколько подходов, но безрезультатно. Это возможно? Поддерживает ли SSRS 2005 динамический SQL? Спасибо!

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
5
0
13 800
8
Перейти к ответу Данный вопрос помечен как решенный

Ответы 8

Возможно, это сработает для вас:

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.

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

Meff 09.10.2008 18:24

Вы также можете выбрать другой подход и использовать функцию 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%')

Редактировать: Также, если вы не используете сохраненную процедуру, используйте ее.

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

λ Jonas Gorauskas 27.09.2008 03:33

Это не работает в случае, если check - false (0). В этом случае он не вернет никаких совпадений, даже если некоторые из них могут существовать.

Anthony K 26.09.2008 09:55

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 параметрами я получил хорошую производительность, не прибегая к ней.

Meff 09.10.2008 15:54

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

AviD 23.02.2009 10:03

Отличный ответ

Artemination 17.01.2020 14:44

если вы можете использовать хранимые процедуры, вероятно, это проще сделать там. передать свои параметры. Создайте строку SQL на основе ваших условий и выполните EXEC для строки sql, ваша сохраненная процедура вернет вам нужные результаты.

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

λ Jonas Gorauskas 27.09.2008 03:39

Другие вопросы по теме