SQL-запрос с условным оператором where работает только иногда

Я создаю отчет (в Crystal Reports XI) на основе хранимой процедуры SQL в базе данных. Запрос принимает несколько параметров и возвращает записи в указанном диапазоне дат. Если параметры передаются, они используются для определения возвращаемых записей. Если один или несколько параметров не переданы, это поле не используется для ограничения типов возвращаемых записей. Это немного сложно, поэтому вот мое предложение WHERE:

WHERE  ((Date > @start_date) AND (Date < @end_date)) 
    AND (@EmployeeID IS NULL OR emp_id = @EmployeeID) 
    AND (@ClientID IS NULL OR client_id = @ClientID)
    AND (@ProjectID IS NULL OR project_id  = @ProjectID)
    AND (@Group IS NULL OR group = @Group)

Теперь о проблеме:

Запрос (и отчет) прекрасно работает со старыми данными в диапазоне 2000–2005 годов. Однако предложение WHERE не фильтрует данные должным образом за более поздние годы: оно возвращает только те записи, в которых параметр @Group имеет значение NULL (т. е. не передается).

Любые подсказки, советы или выводы приветствуются!


person dj18    schedule 02.12.2010    source источник
comment
С точки зрения производительности взгляните на сообщение в блоге Гейл Шоу на все запросы.   -  person Joe Stefanelli    schedule 02.12.2010
comment
Можете ли вы показать остальную часть запроса?   -  person JNK    schedule 02.12.2010
comment
Спасибо, Джо; это информативно.   -  person dj18    schedule 02.12.2010


Ответы (3)


Решено!

В конце концов, на самом деле это не имело ничего общего с предложением WHERE. Я позволил SQL Server сгенерировать для меня внутреннее соединение, которое должно было быть ЛЕВЫМ соединением: многие записи за последние годы не содержат записей в объединенной таблице (расходы), поэтому они не отображались. Интересно, что несколько недавних записей, которые имеют записи в таблице расходов, имеют значение NULL для группы, поэтому я получил записи только тогда, когда @Group был равен NULL.

Мораль этой истории: 1. Дважды проверяйте все, что генерируется автоматически; и 2. Следите за значениями NULL! (n8wl - спасибо, что подсказали мне внимательно посмотреть на NULL.)

person dj18    schedule 12.12.2010

Какова вероятность того, что ваши новые данные (после 2005 г.) содержат строки с NULL в emp_id, client_id, project _id или group? Если они были NULL, они не могут соответствовать параметрам, которые вы передаете.

person n8wrl    schedule 02.12.2010
comment
в группе есть NULL!! Большинство групп строк имеют значение NULL. Как мне обойти это? - person dj18; 02.12.2010
comment
Между прочим, я объявляю все свои параметры начальным значением NULL; это имеет значение? (Я очень новичок в этом!) - person dj18; 02.12.2010

Поскольку дата и группа являются зарезервированными словами, вы можете попробовать заключить поля в квадратные скобки, чтобы они не обрабатывались. Это поможет избавиться от подобных «странных» проблем. Так что это будет:

WHERE  (([Date] > @start_date) AND ([Date] < @end_date)) 
AND (@EmployeeID IS NULL OR emp_id = @EmployeeID) 
AND (@ClientID IS NULL OR client_id = @ClientID)
AND (@ProjectID IS NULL OR project_id  = @ProjectID)
AND (@Group IS NULL OR [group] = @Group)
person Jeff Davis    schedule 02.12.2010