Pergunta

Eu tenho trabalhado em otimizar uma consulta e ter deparou com uma situação que está me fazendo questão de como eu sempre usei SQL do operador OR. (SQL Server 2000 também)

Eu tenho uma consulta onde o condicional (WHERE) cláusula é algo como isto:

WHERE (Column1 = @Param1 or Column1 LIKE @Param1 + '%')
AND (@Param2 = '' OR Column2 = @Param2 OR Column2 LIKE @Param2 + '%')

Agora, eu sempre entendi que OR em SQL avaliadas as duas expressões. Então, todos os registros que avaliaram verdade para a expressão esquerda seria devolvido, juntamente com todos os registros que avaliaram verdade sobre a expressão certa. Por exemplo:

SELECT * FROM TABLE1
WHERE COL1 = 'Test' OR Col2 = 'Data'

Este seria retornar todos os registros em que COL1 is'Test', bem como qualquer registro onde Col2 é 'Dados'

No exemplo acima, que modificou a condicional Coluna2 para o seguinte:

AND(Column2 LIKE ISNULL(@Param2, '') + '%')

De repente, eu recebo 0 linhas retornadas.

Eu fui confundido em que OR avalia apenas expressões até encontrar um resultado VERDADEIRO ou há uma condição que faria com que o 2 diferente para retornar resultados diferentes?

Foi útil?

Solução

"ou somente avalia as expressões até que encontrar um resultado VERDADEIRO"

Ele só tem que, mas isso não é o seu problema (na verdade, isso é o que foi poupando-lhe no seu caso original). Suas duas consultas não são realmente equivalentes.

Eu estou pensando que você tem NULLs em Column2 que nunca causa (Column2 LIKE ISNULL(@Param2, '') + '%') para ser verdade - e em sua versão original do @Param2 = '' foi mascaramento neste caso, uma vez que é verdadeiro (às vezes)

Talvez:

(ISNULL(Column2, '') LIKE ISNULL(@Param2, '') + '%')

Lembre-se da lógica de três valores para NULLs:

TRUE and UNKNOWN: UNKNOWN
TRUE or UNKNOWN: TRUE

FALSE and UNKNOWN: FALSE
FALSE or UNKNOWN: UNKNOWN

Mas eu não estou certo de sua otimização é realmente ajudar.

Outras dicas

ou não é abrangente, especialmente como é entre parênteses. O que você tem em um maior desde é: WHERE X AND Y. O fato de que X e Y são, eles próprios boolean expressões que fazem uso de um ou não é importante:. São avaliados separadamente e então os resultados são enviados para o operador AND

[editar]:
Lendo novamente, eu pode ter entendido mal a sua pergunta. Com isso em mente, eu vou ter que ir com a outra resposta, porque NULL LIKE '%' retorna NULL, que é o mesmo que falsa neste caso. Você pode tentar isso em vez disso:

COALESCE(Column2,'') LIKE COALESCE(@param2,'') + '%'

FYI, existem experiências muito simples que você pode fazer para ver que nem todas as condições são necessariamente avaliadas.

Eu fiz isso no Oracle, mas eu espero que você teria um resultado semelhante no SQL Server.

dev> select * from dual where 1=1 or 1/0 = 3;

D
-
X

não deve ter sido avaliada a condição após o OR, uma vez que iria levantar um erro de divisão por zero.

Esta manipulação de operadores booleanos é geralmente conhecido como "curto-circuito" e, AFAIK, é bastante normal em línguas modernas. Ele também pode aplicar em uma expressão AND -. Se a primeira condição é falsa, não há nenhum ponto na avaliação da segunda condição, uma vez que toda a expressão não pode ser verdade

Mais informações: http://en.wikipedia.org/wiki/Short-circuit_evaluation

De qualquer forma, como Cade disse, o problema real é provavelmente mau uso de nulos.

MS-SQL irá avaliar o lado esquerdo primeiro e não proceder a menos que ele precisa.

Este é o mesmo com o E conector, o lado esquerdo será avaliado e se for falso o direito não será evaulated.

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