patternsqlCritical
Does SQL Server read all of a COALESCE function even if the first argument is not NULL?
Viewed 0 times
theargumentcoalescereadsqlallnullfunctionfirstdoes
Problem
I'm using a T-SQL
If, for example,
I know with the VB.NET
COALESCE function where the first argument will not be null on about 95% of the times it is ran. If the first argument is NULL, the second argument is quite a lengthy process:SELECT COALESCE(c.FirstName
,(SELECT TOP 1 b.FirstName
FROM TableA a
JOIN TableB b ON .....)
)If, for example,
c.FirstName = 'John', would SQL Server still run the sub-query?I know with the VB.NET
IIF() function, if the second argument is True, the code still reads the third argument (even though it won't be used).Solution
Nope. Here's a simple test:
If the second condition is evaluated, an exception is thrown for divide-by-zero.
Per the MSDN Documentation this is related to how
There are some exceptions when comparing to scalar variables and aggregations as shown by Aaron Bertrand in another answer here (and this would apply both to
will generate a division by zero error.
This should be considered a bug, and as a rule
SELECT COALESCE(1, (SELECT 1/0)) -- runs fine
SELECT COALESCE(NULL, (SELECT 1/0)) -- throws errorIf the second condition is evaluated, an exception is thrown for divide-by-zero.
Per the MSDN Documentation this is related to how
COALESCE is viewed by the interpreter - it's just an easy way to write a CASE statement. CASE is well known to be one of the only functions in SQL Server that (mostly) reliably short circuits.There are some exceptions when comparing to scalar variables and aggregations as shown by Aaron Bertrand in another answer here (and this would apply both to
CASE and COALESCE):DECLARE @i INT = 1;
SELECT CASE WHEN @i = 1 THEN 1 ELSE MIN(1/0) END;will generate a division by zero error.
This should be considered a bug, and as a rule
COALESCE will parse from left to right.Code Snippets
SELECT COALESCE(1, (SELECT 1/0)) -- runs fine
SELECT COALESCE(NULL, (SELECT 1/0)) -- throws errorDECLARE @i INT = 1;
SELECT CASE WHEN @i = 1 THEN 1 ELSE MIN(1/0) END;Context
StackExchange Database Administrators Q#12941, answer score: 98
Revisions (0)
No revisions yet.