This means that no rows will be returned if @region is NULL , if they are used in your first example, even if the table has rows in which Region is NULL .
When ANSI_NULLS enabled (which you should always set in any case, since the option not to enable it in the future will be removed), any comparison operation, where (at least) one of the NULL operands yields a third logical value - UNKNOWN (unlike TRUE and FALSE ).
UNKNOWN values ββare propagated through any union of Boolean operators if they are not already defined (for example, AND with the FALSE operand or OR with the TRUE operand) or negatives ( NOT ).
The WHERE used to filter the result set created by the FROM , so the total value of the WHERE must be TRUE so that the row is not filtered. Thus, if UNKNOWN is created by any comparison, this will filter the string.
@ user1227804 answer includes this quote:
If both sides of the comparison are columns or compound expressions, the setting does not affect the comparison.
from SET ANSI_NULLS *
However, I'm not sure at what point it is trying to make, because if you compare two NULL columns (for example, in JOIN ), the comparison still fails:
create table #T1 ( ID int not null, Val1 varchar(10) null ) insert into #T1(ID,Val1) select 1,null create table #T2 ( ID int not null, Val1 varchar(10) null ) insert into #T2(ID,Val1) select 1,null select * from #T1 t1 inner join #T2 t2 on t1.ID = t2.ID and t1.Val1 = t2.Val1
The above query returns 0 rows, whereas:
select * from #T1 t1 inner join #T2 t2 on t1.ID = t2.ID and (t1.Val1 = t2.Val1 or t1.Val1 is null and t2.Val1 is null)
Returns a single row. Therefore, even if both operands are columns, NULL not equal to NULL . And the documentation for = not allowed to talk about operands:
When comparing two NULL expressions, the result depends on the ANSI_NULLS parameter:
If ANSI_NULLS set to ON , the result is NULL 1 following the ANSI convention that NULL (or unknown) is not equal to another NULL or unknown value.
If ANSI_NULLS set to OFF , the result is NULL compared to NULL equal to TRUE .
Comparing NULL with a non- NULL always results in FALSE 2 .
However, both 1 and 2 are incorrect - the result of both UNKNOWN comparisons.
* The mysterious meaning of this text was finally discovered years later. In fact, this means that the setting does not work for these comparisons, and it always acts as if the setting were turned on. It would be clearer if he stated that SET ANSI_NULLS OFF is a parameter that did not affect.