2

For Sql Server 2005 and 2008 I want to check if a column already exists on a given table and create it if it doesn't. This new column should have a default value of an ExistingColumn. Currently I need to use dynamic sql to fill the new column because sql server will complain of a syntax error.

Here is the current sql server code:

IF NOT EXISTS (SELECT TOP 1 1 FROM sys.columns WHERE [name] = N'NewColumn' AND OBJECT_ID = OBJECT_ID(N'ExistingTable'))
BEGIN
    ALTER TABLE [dbo].[ExistingTable] ADD [NewColumn] VARCHAR(50) NULL;

    exec sp_executesql  N'UPDATE [dbo].[ExistingTable] SET NewColumn = ExistingColumn'

    ALTER TABLE [dbo].[ExistingTable] ALTER COLUMN  [NewColumn] VARCHAR(50) NOT NULL 
END
GO

Is there any other way to solve this problem without resorting to dynamic sql?

3
  • 1
    why don't you like dynamic sql as a solution? Commented Mar 7, 2013 at 19:03
  • I don't have a problem with it aside from not getting the syntax highlighting and auto complete of Management Studio. More curious as to whats really going on under the covers. Commented Mar 7, 2013 at 19:04
  • Ah, I usually replace the exec with Print, then paste that in another window it's not brill but it's better that trying to figure out what error near , means Commented Mar 7, 2013 at 20:44

2 Answers 2

2

SQL Server is parsing your statement before your ALTER runs, and saying "Hey, no such column." The parser doesn't understand IF and other branching and can't follow the sequence of events when you mix DDL and DML - or predict the sequence the events will take and what branching will happen at runtime.

Deferred name resolution allows you to access objects that don't exist yet, but not columns that don't exist yet on objects that do.

So, dynamic SQL seems like the way you'll have to do it.

Sign up to request clarification or add additional context in comments.

Comments

1

Since you're creating the column regardless, you could do two separate batches.

    IF NOT EXISTS (SELECT TOP 1 1 FROM sys.columns WHERE [name] = N'NewColumn' AND OBJECT_ID = OBJECT_ID(N'ExistingTable'))
    BEGIN
        ALTER TABLE [dbo].[ExistingTable] ADD [NewColumn] VARCHAR(50) NULL;
    END
    GO
    IF EXISTS (SELECT TOP 1 1 FROM sys.columns WHERE [name] = N'NewColumn' AND OBJECT_ID = OBJECT_ID(N'ExistingTable'))
    BEGIN
        IF EXISTS (SELECT 1 FROM [dbo].[ExistingTable] WHERE NewColumn IS NULL)
        BEGIN
            UPDATE [dbo].[ExistingTable] SET NewColumn = ExistingColumn
            ALTER TABLE [dbo].[ExistingTable] ALTER COLUMN  [NewColumn] VARCHAR(50) NOT NULL 
        END
    END
    GO

1 Comment

It's worth noting that you'll still get the error if you run the second batch on its own without having ran the first batch or if the first batch errors; all the above does is get you out of doing dynamic SQL. So if you're looking for repeatability, then you're stuck.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.