sql >> Databasteknik >  >> RDS >> Sqlserver

Är MS-SQL OCH/ELLER villkorligt (utför kortslutningsutvärdering)?

Det finns ingen garanti för detta beteende.

Ett exempel på kortslutningsutvärdering inte händer med expr1 AND expr2 är

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'

EXISTS(SELECT COUNT(*) FROM master..spt_monitor HAVING COUNT(*)=2) är false (som betyder And -ed uttryck måste vara False ) men IO-resultaten visar att det andra tillståndet fortfarande utvärderades.

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 kan gör detta dock. Jag ser detta i mitt test

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'

Utdata är

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)

Visar spt_values har aldrig nåtts.

Detta implementeras genom ett pass-through-predikatvillkor i utförandeplanen. Det finns lite information om dem här.

Om passthru-predikatet utvärderas till sant, returnerar join raden... Om passthru-predikatet utvärderas till falskt, fortsätter sammanfogningen normalt



  1. SQL - Hur transponerar man?

  2. Hur konverterar man primärnyckel från heltal till seriell?

  3. Konvertera 'tid' till 'smalldatetime' i SQL Server (T-SQL-exempel)

  4. Hur man konverterar ett datum-/tidsvärde till en sträng i SQL Server med CONVERT()