No value will ever equal (or "unequal") NULL in SQL. Understand the following truth table:
NULL = NULL yields NULL -- not FALSE!
NULL != NULL yields NULL -- not TRUE!
[ANY] = NULL yields NULL -- not FALSE!
[ANY] != NULL yields NULL -- not TRUE!
Since the following are equivalent...
[expression] IN (a, b, c)
[expression] = ANY (a, b, c)
[expression] = a OR [expression] = b OR [expression] = c
... you cannot put NULL on the right hand side of an IN predicate. Interestingly, things get even worse when you put NULL on the right hand side of a NOT IN predicate:
[expression] NOT IN (a, b, c)
[expression] != ANY (a, b, c)
[expression] != a AND [expression] != b AND [expression] != c
If b were NULL, the whole expression will become NULL (or maybe FALSE), but never TRUE. This is also the case for NOT IN (subselect) predicates! So, never do this:
[expression] NOT IN (NULL, 1, 2)
The correct solution in your case uses a NULL predicate instead. Do this:
UPDATE Details
SET HowHear_ID = CASE
WHEN HowHear_ID = '' THEN 25
WHEN HowHear_ID IS NULL THEN 25 -- Use a NULL predicate here
WHEN HowHear_ID = 7 THEN 25
WHEN HowHear_ID = 8 THEN 5
WHEN HowHear_ID = 16 THEN 25
WHEN HowHear_ID = 17 THEN 16
END
WHERE HowHear_ID IN ('',7,8,16,17)
OR HowHear_ID IS NULL -- Use a NULL predicate here
Or this:
WHERE COALESCE(HowHear_ID, '') IN ('',7,8,16,17)