Pergunta

Eu li sobre o uso da expressão CASE dentro da cláusula WHERE aqui:

http: // scottelkin. com / sql / utilizando-a-caso-statement-in-a-SQL onde cláusula /

Eu estou tentando usar isso para filtrar os resultados de minha instrução select, com base em um número de contrato que será passado pelo aplicativo do usuário. Meu código atualmente gera um erro de 'parâmetro inválido' não importa o que é passado. Eu verificada SELECT / DA estão funcionando bem, como onde, como uma cláusula WHERE sem uma expressão CASE. Aqui está o meu código.

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

A redundância do código é para fins de solução de problemas, eu estou pensando em usar filtragem curinga sobre o caso mais tarde. Estou focando em obter a sintaxe para baixo agora. Eu acredito que este deve retornar todos os registros para o qual o parâmetro coincide com o número do contrato armazenados na tabela. Qualquer ajuda ou conselhos seria muito apreciada.

Foi útil?

Solução

Depois de ler sua explicação, não há uma maneira melhor de fazer isso sem CASE:

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

Isto irá retornar apenas combinando números de contrato, a menos que @ContractNo é 0, caso em que ele irá retornar todos os registros.

Editar: eu só notei que casperOne propôs a mesma coisa . Eu não vi isso. Big-se a si mesmo.

Outras dicas

Você tem certeza que quer fazer isso? Sua declaração caso sempre retorna @ContractNo. Eu acho que o que você está procurando é a seguinte:

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

O filtro acima diz "dá-me o contrato onde o ContractNo é igual ao parâmetro, ou todos eles se o parâmetro for 0.

O filtro anterior só filtrada onde o campo número do contrato é exatamente igual ao parâmetro.

Independentemente disso, você deve fazer isso em vez disso:

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

A lógica é muito mais fácil de entender, e em cima disso (não citar-me sobre isso), o otimizador provavelmente irá funcionar melhor fora da instrução caso.

Tente deixando de fora os parênteses que estão no lugar errado de qualquer maneira -. O caminho certo deve ser depois "END"

Talvez você se esqueceu de declarar @ContractNo? É comparável a 0 e tblContracts.ContractNo?

O post de recursiva resolvido meu problema com precisão.

Eu vi reclamações sobre a clareza do meu post original. No futuro, o que eu posso fazer para fazer o que estou dizendo mais para a frente? Eu não estou acostumado a fraseado perguntas sobre o código, e pedimos desculpas por quaisquer coisas confusa que tinha. Eu só precisa fornecer os detalhes prolongados como na minha segunda mensagem?

Obrigado novamente por toda a ajuda.

Mover seu próximo parêntesis para antes das = assim:

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

Não consigo ver o que esta afirmação caso fará embora ... você está retornando a mesma coisa no caso do @ContractNo = 0 ou não se é ...

A sintaxe correta é:

  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>

Independentemente da sintaxe, porém, o seu exemplo não faz muito sentido, se você estiver olhando para todos os itens que correspondem ou ter um contrato Número de 0, então você faria:

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

O que parece fazer muito mais sentido do que o que você está tentando usar a instrução caso para.

Editar: Eu devo ter interpretado mal a pergunta ligeiramente - o param faltando geralmente significa que o parâmetro (neste caso @ContractNo) não é declarado no âmbito da sua consulta / procedimento. Mas alguém já salientaram, por isso não posso tomar nenhum crédito por isso.

A razão para a exposição do caso, incluindo o todo "Se for 0, dar o parâmetro, e de outra forma, apenas dar o parâmetro" foi para testá-lo para tentar obter o direito de sintaxe. Originalmente, eu tinha tentado a dizer "Se for 0, em seguida, passar em '%', para retornar todos os valores. O código eu postei lá foi porque eu continuei recebendo 'Parâmetro inválido' e percebi que deve haver algo errado com a minha sintaxe. Quando separei-lo em correspondência parâmetro básico como assim,

WHERE @ContractNo = tblContracts.ContractNo

retornou registros bem. Deixe-me explicar um pouco mais.

Eu estou puxando de um grupo de tabelas diferentes, e filtrar o conteúdo com informações não incluídas na instrução SELECT (ou seja tblContracts é não ter informações extraídas dele por Select, ele só é usado em caso). O usuário irá selecionar a partir de uma caixa de combinação que terá os diferentes números de contrato, bem como um valor padrão de 'All'.

Eu vou ter um evento para quando o índice da caixa de combinação muda. Se é 'All', 0 será passado como um parâmetro e quero nenhuma filtragem feito. Caso contrário, eu só quero as informações para esse número de contrato (o motivo para @ContractNo Else).

Você não quer dizer algo como isto?

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

Onde @ContractNo é variável do mesmo tipo de dados como tblContracts.ContractNo

Por que você ainda precisa de uma instrução case?

Quando @ContractNo = 0 então (0 = tblContracts.ContractNo) outra @ContractNo então (@ContractNo = tblContracts.ContractNo)

Isso não faz sentido uma vez que você poderia simplesmente escrever isto como

Onde @contractNo = tblContracts.contractNo

é o número do contrato, na verdade, um código numérico ou é uma cadeia que sempre acontece a ser um numérico. Verifique os seus tipos de dados entre a mesa e o parâmetro ea instrução CASE (por exemplo, "= 0" ou "= '0'")

Esta sintaxe deve trabalhar (ele faz em Oracle)

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

quando você diz:

Eu estou puxando de um grupo de tabelas diferentes, e filtrar o conteúdo com informações não incluídas na instrução SELECT (ou seja tblContracts é não ter informações extraídas dele por Select, ele só é usado em caso). O usuário irá selecionar a partir de uma caixa de combinação que terá os diferentes números de contrato, bem como um valor padrão de 'All'.

Em seguida, parece-me que deve ter uma cláusula de "Onde existe". desde a sua não puxar qualquer informação fora dessa mesa?!

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top