Software Development

Behind the scenes

How a NULL in T-SQL Nearly Nullified My Sanity (A Merge Misadventure)

We’ve all had those “facepalm” moments in coding — the kind where you stare at a line of SQL for an hour, convinced it should work. This is the story of one such moment involving a MERGE statement in T-SQL, a sneaky nullable column, and a silent refusal to update anything.

If you’ve ever screamed internally at a query that “should work but doesn’t,” this one’s for you.

The Problem

I was trying to sync data between two tables using a MERGE statement — standard stuff. I wanted to update rows where the Price field had changed. My condition looked like this:

WHEN MATCHED AND target.Price <> source.Price THEN UPDATE ...

Perfectly logical, right? Wrong.

Despite clear differences in price values between the tables, my MERGE quietly skipped rows. No errors, no warnings. Just… nothing.

It took me far too long to realize the culprit: target.Price was nullable. And in SQL, NULL <> something doesn’t return TRUE — it returns UNKNOWN. And MERGE ignores UNKNOWN in its conditions.

The Solution

Once I remembered how SQL handles NULLs, the fix was obvious (and slightly embarrassing):

WHEN MATCHED AND ISNULL(target.Price, -1) <> source.Price THEN UPDATE …

Here’s the catch — source.Price was not nullable, so I only needed to NULL-protect target.Price. No need to wrap both sides in ISNULL() — just making sure one side isn’t floating off in NULL-space was enough.

After that? It worked like a charm.

Deeper Explanation

NULLs are tricky beasts. In SQL, they represent “unknown,” and any comparison with NULL — even NULL <> 5 — is never TRUE, just UNKNOWN. And MERGE only acts on rows where the condition is explicitly TRUE.

So if target.Price is NULL and source.Price is 100.00, SQL shrugs: “Could be different, could be the same. I dunno.” And the update gets skipped.

By using ISNULL(target.Price, -1), I forced the comparison to a known value. Since source.Price was declared NOT NULL, I didn’t need to touch it.

Best Practices

  • Always consider NULLs when comparing fields in MERGE, especially with <> and =.
  • NULL-protect only the fields that can be NULL. Don’t overuse ISNULL() unnecessarily.
  • Pick a safe default (like -1) that won’t collide with real data.
  • Test your MERGE conditions with edge cases — including NULLs.

Conclusion

This bug was a classic case of forgetting how SQL really thinks. It wasn’t a syntax error. It wasn’t a typo. It was a logic trap — and one that quietly skipped the updates I needed.

But hey, that’s the daily grind of writing code — learning, relearning, and occasionally yelling at NULLs.

Stick around for more real-world lessons from the coding trenches. Spoiler: the bugs aren’t going anywhere.


Leave a Reply

Your email address will not be published. Required fields are marked *

About Me

I’m a software developer sharing thoughts, tips, and lessons from everyday coding life — the good, the bad, and the buggy.