T-SQL / Unexpected NULL handling when ANSI_NULLS is turned OFF

Viewed 252

I'm just struggling with the NULL value handling in SQL Server (tested on Version 12.0.5000.0). Basically, my intention is to get all rows that have a column value <> a static value (e.g. 999). I'm NOT searching for an alternative LIKE "use the ISNULL function". The query is generated by a third-party engine and I do not intend write a parser and change the statement.

-- All examples with ANSI_NULLS OFF
SET ANSI_NULLS OFF;
GO

--------------------------------------------------------------------------------------------------------
-- "Virtual" example / working as expected
--------------------------------------------------------------------------------------------------------
    DECLARE 
        @One INT = 1,
        @Null INT = NULL

    SELECT
         IIF(@Null = NULL, 1, 0) '@Null = NULL' -- To test if ANSI_NULL is OFF
        ,IIF(@One <> NULL, 1, 0) '@One <> NULL' -- working with NULL variable
        ,IIF(1 <> NULL, 1, 0) '1 <> NULL'       -- working with NULL value

--------------------------------------------------------------------------------------------------------
-- MSDN Example / NOT working as expected
    -- https://docs.microsoft.com/en-us/sql/t-sql/statements/set-ansi-nulls-transact-sql
--------------------------------------------------------------------------------------------------------

    -- Create table t1 and insert values.  
    CREATE TABLE dbo.t1 (a INT NULL);  
    INSERT INTO dbo.t1 values (NULL),(0),(1);  
    GO  

    -- SET ANSI_NULLS to OFF and test.  
    DECLARE @varname int;  
    SET @varname = 999;

    SELECT a   
    FROM t1   
    WHERE a <> @varname;    -- working with NULL variable

    SELECT a   
    FROM t1   
    WHERE a <> 999;         -- NOT working with NULL value

    -- Drop table t1.  
    DROP TABLE dbo.t1;  

Could anyone explain why the "virtual" example is working in a different way then the MSDN example?

Virtual example:
+--------------+--------------+-----------+
| @Null = NULL | @One <> NULL | 1 <> NULL |
+--------------+--------------+-----------+
|            1 |            1 |         1 |
+--------------+--------------+-----------+

MSDN example:
-- SELECT 1
+------+
|  a   |
+------+
| NULL |
| 0    |
| 1    |
+------+

-- SELECT 2
+------+
|  a   |
+------+
| 0    |
| 1    |
+------+
1 Answers
Related