Pregunta

He estado trabajando para optimizar una consulta y me he encontrado con una situación que me hace preguntarme cómo siempre he usado el operador OR de SQL. (SQL Server 2000 también)

Tengo una consulta donde la cláusula condicional (WHERE) se parece a esto:

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

Ahora, siempre he entendido que OR en SQL evaluó ambas expresiones. Por lo tanto, todos los registros que evaluaron verdadero para la expresión izquierda se devolverían junto con todos los registros que evaluaron verdadero en la expresión correcta. Por ejemplo:

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

Esto devolvería todos los registros donde COL1 es 'Prueba', así como cualquier registro donde Col2 es 'Datos'

En el ejemplo anterior, modifiqué la Columna2 condicional a lo siguiente:

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

De repente, me devuelven 0 filas.

¿Me he equivocado al decir que O solo evalúa expresiones hasta que encuentra un resultado VERDADERO o hay una condición que haría que los 2 diferentes arrojen resultados diferentes?

¿Fue útil?

Solución

" OR solo evalúa expresiones hasta que encuentra un resultado VERDADERO "

Solo tiene que hacerlo, pero ese no es tu problema (en realidad, esto es lo que te estaba salvando en tu caso original). Sus dos consultas no son realmente equivalentes.

Estoy pensando que tiene NULL s en Column2 que nunca hará que (Column2 LIKE ISNULL (@ Param2, '') + '%') sea verdadero - y en su versión original, el @ Param2 = '' estaba enmascarando este caso, ya que ES cierto (a veces)

Quizás:

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

Recuerde la lógica de tres valores para NULL:

TRUE and UNKNOWN: UNKNOWN
TRUE or UNKNOWN: TRUE

FALSE and UNKNOWN: FALSE
FALSE or UNKNOWN: UNKNOWN

Pero no estoy seguro de que su optimización realmente esté ayudando.

Otros consejos

OR no lo abarca todo, especialmente porque está entre paréntesis. Lo que tienes en un más grande desde entonces es: WHERE X AND Y . El hecho de que X e Y sean expresiones booleanas que hacen uso de un OR no es importante: se evalúan por separado y luego los resultados se envían al operador AND.

[editar]:
Leyendo de nuevo, puedo haber entendido mal su pregunta. Con eso en mente, tendré que ir con la otra respuesta, porque NULL LIKE '%' devuelve NULL, que es lo mismo que falso en este caso. Puede probar esto en su lugar:

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

Para su información, hay experimentos muy simples que puede hacer para ver que no todas las condiciones se evalúan necesariamente.

Hice esto en Oracle pero espero que tenga un resultado similar en SQL Server.

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

D
-
X

La condición después del OR no debe haber sido evaluada, ya que generaría un error de división por cero.

Este manejo de operadores booleanos se conoce generalmente como "cortocircuito" y, AFAIK, es bastante estándar en los idiomas modernos. También puede aplicarse en una expresión AND: si la primera condición es falsa, no tiene sentido evaluar la segunda condición, ya que toda la expresión no puede ser VERDADERA.

Más información: http://en.wikipedia.org/wiki/Short-circuit_evaluation

De todos modos, como dijo Cade, su verdadero problema probablemente sea el mal manejo de los NULL.

MS-SQL evaluará primero el lado izquierdo y no procederá a menos que sea necesario.

Esto es lo mismo con el conector AND, se evaluará el lado izquierdo y, si es falso, el derecho no se evaluará.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top