I made a mistake when updating code and ended up with this situation (I renamed the column in a table variable and missed renaming where it was used)...
CREATE TABLE MyTable (Id INT, OtherCol VARCHAR(100));
-- populate with lots of data, just a demo here
INSERT MyTable(Id) VALUES (1, 'bla'), (2, 'bla'), (3, 'bla'), (4, 'bla');
DECLARE @TableVar TABLE (MyCol INT);
-- populate the table variable somehow, e.g. ...
INSERT @TableVar VALUES (1);
UPDATE MyTable
SET OtherCol = 'Some value'
WHERE Id IN (SELECT Id FROM @TableVar);
The mistake is that the Id
column in the IN (SELECT...)
should have been MyCol
of course, but I didn't expect the following behaviour...
- If
@TableVar
contains no rows, no update is done at all - I expected that - If
@TableVar
contains any rows, every row inMyTable
is updated I would have expected that if@TableVar
included one row, that the(SELECT...)
would return one row, though I'm not sure what value I'd expect in theId
column.
The code isn't great anyway for various reasons, but that behaviour of an IN (SELECT...)
where a column name from the outer query is referenced acting as if it matched every row surprised me (and made it a very nasty error).
Am I just dumb to be so surprised by this? What does SQL Server actually make out of that statement?