Why does checking an existing column fail in SQL?

I have this SQL script change that runs as part of my created or updated database creation or update:

SET XACT_ABORT ON
BEGIN TRANSACTION

PRINT 'Change MyColumn column to MyNewColumn column in MyTable table'
IF EXISTS (SELECT *
           FROM sys.columns
           WHERE Name = 'MyColumn' AND Object_id = OBJECT_ID('[dbo].[MyTable]'))
BEGIN
    PRINT '-> Exists, change it'
    /* NOTE THE NEXT LINE */
    SET @Value = (SELECT MyColumn FROM [dbo].[MyTable])

    ALTER TABLE [dbo].[MyTable]
    DROP CONSTRAINT DF_MyTable_MyColumn

    ALTER TABLE [dbo].[MyTable]
    DROP COLUMN MyColumn

    ALTER TABLE [dbo].[MyTable]
    ADD MyNewColumn nvarchar(20) NULL

    ALTER TABLE [dbo].[MyTable]
    ADD CONSTRAINT DF_MyTable_MyNewColumn DEFAULT ('') FOR MyNewColumn

    PRINT '-> Add values back into table'
    SET @Dynamic_Sql = 'UPDATE [dbo].[MyTable] SET MyNewColumn = ''' + @Value + ''''
    EXEC(@Dynamic_Sql)

    PRINT '-> Alter to NOT NULL'
    ALTER TABLE [dbo].[MyTable]
    ALTER COLUMN MyNewColumn nvarchar(20) NOT NULL
END
ELSE
BEGIN
PRINT '-> Does not exist, skip it'
END

I already ran this update script before and made changes to the database (so MyColumn no longer exists). But now I have a new script that appears after that, but my “build” crashes in this line of this script with:

Msg 207, Level 16, State 1, Line 15 Invalid column name "MyColumn"

where line 15 is the FROM sys.columns line. But in fact, he complains about the line that I have inside the IF statement, where I added a NOTE comment. Why should this be behavior? Of course, the column name will be invalid if it no longer exists.

+3
2

GO ? , , - .

GO, , .

+2

( , ) , SQL Server script. , MyColumn , . , IF.

script:

CREATE TABLE dbo.Test (my_id int)
GO
IF (1=0)
    SELECT blah FROM Test

, , SQL, , .

EDIT: . , .

CREATE FUNCTION dbo.Get_my_id ()
RETURNS INT
AS
BEGIN
    DECLARE @my_id INT
    SELECT @my_id = blah FROM dbo.Test
    RETURN @my_id
END
GO
CREATE TABLE dbo.Test (my_id INT)
GO
DECLARE @my_id INT

IF (1=0)
    SELECT @my_id = dbo.Get_my_id()
GO

, , , , ?

+2

Source: https://habr.com/ru/post/1759563/


All Articles