Why does the T-SQL block give an error even if it doesn't even execute?

I wrote a (apparently) straightforward SQL fragment that deletes a column after it ensures that the column exists.
Problem: if the column does NOT exist, the code inside the IF clause complains that it cannot find the column! Well, yes, why is it inside an IF clause!
So my question is: why does the part of the code that should not be executed give errors?

Here's a snippet:

IF exists (select * from syscolumns
    WHERE id=object_id('Table_MD') and name='timeout')
BEGIN
    ALTER TABLE [dbo].[Table_MD]
        DROP COLUMN timeout
END
GO

... and here's the error:

Error executing SQL script [...]. Invalid column name 'timeout'

I am using Microsoft SQL Server 2005 Express Edition.

+5
source share
4 answers
IF exists (select * from syscolumns
    WHERE id=object_id('Table_MD') and name='timeout')
BEGIN
    DECLARE @SQL nvarchar(1000)
    SET @SQL = N'ALTER TABLE [dbo].[Table_MD] DROP COLUMN timeout'
    EXEC sp_executesql @SQL
END
GO

: Sql , ( ). "IF", ​​ "WHILE" ..... .

+10

, Sql Server. "" - sql,

0

:

IF ALTER ... DROP ... exec ('ALTER ... DROP ...')

It seems that the SQL server checks the validity of the code when it is parsed and sees that a non-existent column is mentioned somewhere (even if this piece of code is never executed). Using the command exec(ute)wraps the problematic code in the line, the parser does not complain, and the code is launched only when necessary. Here's the modified snippet:

IF exists (select * from syscolumns
    WHERE id=object_id('Table_MD') and name='timeout')
BEGIN
    exec ('ALTER TABLE [dbo].[Table_MD] DROP COLUMN timeout')
END
GO
0
source

By the way, there is a similar problem in Oracle and a similar workaround using the "do it right" clause.

0
source

All Articles