Strange behavior with temp tables - is it a bug or normal behavior?!

  • We encountered very strange behavior when using temp tables.

    Steps are:

    Create a temp table 1 and add data (you can use an "into" clause to dynamically create the temp table)

    Then create a temp table 2 derived from the first temp table 1, minus a column

    Finally, execute a select (or an update) statement where you reference the missing column

    using an "in" clause, and select the missing column from temp table 2

    Logically, this column doesn't exist in the temp table 2 so an error should occur...right?

    However, instead, the script executes as if the "in" clause simply doesn't exist!

    Here is a sample script:

    --create a table temp1

    select 'test1' as test1, 'test2' as test2, 'test3' as test3

    into #temp1

    --select 2 fields into temp2

    select test2, test3

    into #temp2

    from #temp1;

    --select from temp1 with field that's in temp2

    --works as expected

    select * from #temp1

    where test2 in (select test2 from #temp2)

    --select from temp1 with field that doesn't exist anywhere

    --select from temp1 with field that's not in temp2, but IS in temp1

    --DOESN'T CAUSE ERROR?

    select * from #temp1

    where test1 in (select test1 from #temp2)

    --causes error as expected

    select * from #temp1

    where test2 in (select foo from #temp2)

    Is this normal behavior?

    The worst thing about uncovering this is instead of a select, I was executing an update script, which inadvertently caused the entire table to update as opposed to select records...

    Also, one last thing...if you execute the statement "select test1 from #temp2" outside of the parenthesis, it renders an error!!

    Is this normal behavior, or a bug in SQL Server?

  • Learn to alias your tables.

    SELECT *

    FROM #temp1

    WHERE test1 IN (

    SELECT test1 --refers to #temp1

    FROM #temp2

    );

    SELECT *

    FROM #temp1

    WHERE test1 IN (

    SELECT a.test1 --refers to #temp2 and will error

    FROM #temp2 a

    );

    What you actually wrote was this: -

    SELECT *

    FROM #temp1

    WHERE test1 = test1;


    Forever trying to learn
    My blog - http://www.cadavre.co.uk/
    For better, quicker answers on T-SQL questions, click on the following...http://www.sqlservercentral.com/articles/Best+Practices/61537/
    For better, quicker answers on SQL Server performance related questions, click on the following...http://www.sqlservercentral.com/articles/SQLServerCentral/66909/

  • Nothing to do with temp tables and not a bug.

    A subquery (like with an IN) can reference any column in the tables inside the subquery or outside the subquery. Otherwise we couldn't have correlated subqueries.

    Your query resolves to

    select * from #temp1 t1

    where t1.test1 in (select t1.test1 from #temp2 t2)

    Perfectly valid. Probably not what you meant, but perfectly valid. Qualify your column names, always. If you do that, the query would have given the expected error

    select * from #temp1 t1

    where t1.test1 in (select t2.test1 from #temp2 t2) -- error

    Gail Shaw
    Microsoft Certified Master: SQL Server, MVP, M.Sc (Comp Sci)
    SQL In The Wild: Discussions on DB performance with occasional diversions into recoverability

    We walk in the dark places no others will enter
    We stand on the bridge and no one may pass
  • Lesson learned...

    I thought by separating the temp table 2 statement in parenthesis, it was separated from the temp table 1 statement, and no alias would be needed...

    Won't make that error again...

    Thanks!

  • Robert Heynen-454800 (8/1/2012)


    Lesson learned...

    I thought by separating the temp table 2 statement in parenthesis, it was separated from the temp table 1 statement, and no alias would be needed...

    If that were true, then this wouldn't work:

    SELECT * FROM #temp1 t1 WHERE EXISTS (SELECT 1 FROM #temp2 t2 WHERE t1.SomeColumn = t2.SomeOtherColumn)

    Nor would any other correlated subquery.

    Gail Shaw
    Microsoft Certified Master: SQL Server, MVP, M.Sc (Comp Sci)
    SQL In The Wild: Discussions on DB performance with occasional diversions into recoverability

    We walk in the dark places no others will enter
    We stand on the bridge and no one may pass
  • GilaMonster (8/1/2012)


    Robert Heynen-454800 (8/1/2012)


    Lesson learned...

    I thought by separating the temp table 2 statement in parenthesis, it was separated from the temp table 1 statement, and no alias would be needed...

    If that were true, then this wouldn't work:

    SELECT * FROM #temp1 t1 WHERE EXISTS (SELECT 1 FROM #temp2 t2 WHERE t1.SomeColumn = t2.SomeOtherColumn)

    Nor would any other correlated subquery.

    Thanks!

Viewing 6 posts - 1 through 5 (of 5 total)

You must be logged in to reply to this topic. Login to reply