Вопрос

Я читал об использовании выражения CASE внутри предложения WHERE:

http: // scottelkin. ком / SQL / с использованием-а-случай-заявление-в-SQL-где-пункт /

Я пытаюсь использовать это для фильтрации результатов из моего оператора выбора на основе номера контракта, который будет передан приложением пользователя. Мой код в настоящий момент выдает ошибку «Неверный параметр», независимо от того, что передано. Я проверил, что SELECT / FROM работают нормально, например, как предложение WHERE без выражения CASE. Вот мой код.

WHERE     (CASE WHEN @ContractNo = 0 THEN @ContractNo ELSE @ContractNo END =
tblContracts.ContractNo)

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

Это было полезно?

Решение

После прочтения вашего объяснения есть лучший способ сделать это без CASE :

WHERE @ContractNo = 0 OR tblContracts.ContractNo = @ContractNo

Это вернет только совпадающие номера контракта, если @ContractNo не равно 0, и в этом случае он вернет все записи.

Изменить . Я только что заметил, что casperOne предложил то же самое . Я этого не видел. Сделай сам.

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

Вы уверены, что хотите это сделать? Ваша выписка с делом ВСЕГДА возвращает @ContractNo . Я думаю, что вы ищете это:

where 
    case @ContractNo 
        when 0 then tblContracts.ContractNo 
        else @ContractNo 
    end = tblContracts.ContractNo

Приведенный выше фильтр говорит: "дайте мне контракт, в котором ContractNo равен параметру, или все из них, если параметр равен 0.

Предыдущий фильтр фильтруется только в том случае, если поле номера контракта точно равно параметру.

В любом случае, вы должны сделать это вместо этого:

where @ContractNo = 0 or @ContractNo = tblContracts.ContractNo

Логика намного проще для понимания, и, кроме того (не цитируйте меня об этом), оптимизатор, вероятно, будет работать лучше вне оператора case.

Попробуйте опустить скобки, которые в любом случае находятся в неправильном месте - правильные должны быть после "END".

Может быть, вы забыли объявить @ContractNo? Это сопоставимо с 0 и с tblContracts.ContractNo?

Пост рекурсии решил мою проблему точно.

Я видел жалобы на ясность моего исходного поста. Что я могу сделать в будущем, чтобы сделать то, что я говорю, более понятным? Я не привык формулировать вопросы о коде и извиняться за любые запутанные вещи, которые у него были. Мне просто нужно было предоставить расширенную информацию, как в моем втором посте?

Еще раз спасибо за помощь.

Переместите закрывающую скобку до символа =, как показано ниже:

WHERE     (CASE WHEN @ContractNo = 0 THEN @ContractNo ELSE @ContractNo END)=tblContracts.ContractNo

Я не вижу, что будет делать этот оператор case, хотя ... вы возвращаете то же самое в случае @ContractNo = 0 или, если это не так ...

Правильный синтаксис:

  Select...
  ...
  Where(
    Case
      When <Condition>
        Then <Return if true>
        Else <Return if false>
      End
 ) = <Whatever is being matched to the output of the case statement>

Независимо от синтаксиса, ваш пример не имеет большого смысла, если вы ищете все элементы, которые соответствуют или имеют номер контракта 0, то вы бы сделали:

Select...
...
Where (
  @ContractNo = 0 Or
  @ContractNo = tblContracts.ContractNo
)

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

Edit: Я, должно быть, немного неправильно прочитал вопрос - отсутствующий параметр обычно означает, что параметр (в данном случае @ContractNo) не объявлен в объеме вашего запроса / процедуры. Но кто-то уже указывал на это, так что я не могу взять на себя ответственность за это.

Причина оператора case, включая целое " Если оно равно 0, укажите параметр, а в противном случае просто укажите параметр " было проверить его, чтобы попытаться получить правильный синтаксис. Первоначально я пытался сказать "Если это 0, то передайте"% ", чтобы вернуть каждое значение. Код, который я разместил там, был потому, что я продолжал получать «Неверный параметр» и решил, что с моим синтаксисом что-то не так. Когда я разделил его на базовое сопоставление параметров следующим образом,

WHERE @ContractNo = tblContracts.ContractNo

он вернул записи в порядке. Позвольте мне объяснить немного больше.

Я извлекаю данные из множества разных таблиц и фильтрую содержимое по информации, не включенной в оператор выбора (т. е. tblContracts не получает информацию, извлекаемую из него с помощью Select, она используется только в Where). Пользователь будет выбирать из поля со списком, в котором будут разные номера контрактов, а также значение по умолчанию «Все».

У меня будет событие, когда изменится индекс поля со списком. Если это «Все», 0 будет передано в качестве параметра, и я не хочу, чтобы была выполнена фильтрация. В противном случае мне просто нужна информация для этого номера контракта (причина Else @ContractNo).

Разве вы не имеете в виду что-то подобное?

SELECT * 
    FROM tblContracts
    WHERE     
    CASE 
       WHEN tblContracts.ContractNo = 0 THEN @ContractNo 
       ELSE tblContracts.ContractNo
    END = tblContracts.ContractNo

Где @ContractNo - это переменная того же типа данных, что и tblContracts.ContractNo

Зачем вам вообще нужна выписка по делу?

WHen @ContractNo = 0 затем (0 = tblContracts.ContractNo) иначе @ContractNo then (@ContractNo = tblContracts.ContractNo)

Это не имеет смысла, так как вы можете просто написать это как

Где @contractNo = tblContracts.contractNo

Номер контракта на самом деле числовой или строка, которая всегда оказывается числовой. Проверьте ваши типы данных между таблицей и параметром и оператором CASE (например, "= 0" или "=" 0 ")

Этот синтаксис должен работать (он работает в Oracle)

WHERE CASE WHEN tblContracts.ContractNo = 0 
           THEN @ContractNo 
           ELSE tblContracts.ContractNo
      END = tblContracts.ContractNo

когда вы говорите:

  

Я извлекаю данные из множества разных таблиц и фильтрую содержимое по информации, не включенной в оператор выбора (т. е. tblContracts не получает информацию, извлекаемую из него с помощью Select, она используется только в Where). Пользователь будет выбирать из поля со списком, в котором будут разные номера контрактов, а также значение по умолчанию «Все».

Тогда мне кажется, что должно быть "Где существует" пункт. так как вы не вытаскиваете какую-либо информацию из этой таблицы?!

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top