Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does a T-SQL block give an error even if it shouldn't even be executed?

Tags:

sql

tsql

I was writing a (seemingly) straight-forward SQL snippet that drops a column after it makes sure the column exists.
The problem: if the column does NOT exist, the code inside the IF clause complains that it can't find the column! Well, doh, that's why it's inside the IF clause!
So my question is, why does a piece of code that shouldn't be executed give errors?

Here's the 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'm using Microsoft SQL Server 2005 Express Edition.

like image 634
Cristian Diaconescu Avatar asked Sep 23 '08 13:09

Cristian Diaconescu


People also ask

What causes SQL blocking?

As mentioned previously, in SQL Server, blocking occurs when one session holds a lock on a specific resource and a second SPID attempts to acquire a conflicting lock type on the same resource. Typically, the time frame for which the first SPID locks the resource is small.

What is SQL blocking?

Blocking in SQL servers happens when a connection to SQL server blocks one or more query, and another connection to SQL server requires a conflicting lock type on query, or query locked by the primary connection. This leads to the another connection waiting until the primary connection releases its locks.

How do I monitor a block in SQL Server?

Using system_health extended event to monitor SQL Server blocking problems. The system_health is the default extended event session of the SQL Server. It is started automatically when the database engine is started. The system_health captures any session that has waited in the blocked status for over 30 seconds.


1 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

Reason: When Sql server compiles the code, they check it for used objects ( if they exists ). This check procedure ignores any "IF", "WHILE", etc... constructs and simply check all used objects in code.

like image 124
TcKs Avatar answered Oct 15 '22 17:10

TcKs