operador de SQL 'Or'. Como funciona no seguinte cenário?
-
19-08-2019 - |
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?
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 NULL
s 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.