sql >> Base de Datos >  >> RDS >> Sqlserver

¿Es MS-SQL AND/OR condicional (realizar una evaluación de cortocircuito)?

No hay garantía de este comportamiento.

Un ejemplo de evaluación de cortocircuito no pasando con expr1 AND expr2 es

SET STATISTICS IO ON

IF EXISTS(SELECT COUNT(*) FROM master..spt_monitor HAVING COUNT(*)=2)  
AND EXISTS (SELECT COUNT(*) FROM master..spt_values HAVING COUNT(*)=1)
PRINT 'Y'

El EXISTS(SELECT COUNT(*) FROM master..spt_monitor HAVING COUNT(*)=2) es false (que significa And La expresión -ed debe ser False ) pero los resultados de IO muestran que la segunda condición aún se evaluó.

Table 'spt_values'. Scan count 1, logical reads 14, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'spt_monitor'. Scan count 1, logical reads 1, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

SQL Server puede haz esto sin embargo. Veo esto en mi prueba

SET STATISTICS IO ON

DECLARE @p1 BIT = NULL

IF ( @p1 = 1
     AND EXISTS(SELECT *
                FROM   master..spt_values) )
  PRINT '1'

ELSE IF ( @p1 = 0
     AND EXISTS(SELECT *
                FROM   master..spt_values) )
  PRINT '2'

La salida es

Table 'Worktable'. Scan count 0, logical reads 0, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

(1 row(s) affected)
Table 'Worktable'. Scan count 0, logical reads 0, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

(1 row(s) affected)

Mostrando spt_values nunca se accedió.

Esto se implementa mediante una condición de predicado de transferencia en el plan de ejecución. Aquí hay información sobre ellos.

Si el predicado de paso se evalúa como verdadero, la unión devuelve la fila.... Si el predicado de paso se evalúa como falso, la unión procede normalmente