Create column and insert into it within the same transaction?

三世轮回 提交于 2019-12-10 02:09:51

问题


Is it possible to create a column and insert values to it during the same transaction? This is part of an upgrade script. I found the following method online, but it does not work; I get an error: Invalid column name 'IndexNumber'.. I'm assuming this is because the transaction hasn't created the column yet so there is nothing to insert to.

The relevant parts of my script:

Print 'Beginning Upgrade'
Begin Transaction
    -- --------------------------------------------------------------------
    USE [MyDatabase];

    /* Widgets now can be ordered and the order can be modified */
    ALTER TABLE [dbo].[Widgets] ADD [IndexNumber] [int] NULL;

    DECLARE @ind INT 
    SET @ind = 0 
    UPDATE [dbo].[Widgets]
    SET @ind = [IndexNumber] = @ind + 1;

    ALTER TABLE [dbo].[Widgets] ALTER COLUMN [IndexNumber] [int] NOT NULL;
    -- --------------------------------------------------------------------
Commit tran
Print 'Upgrade completed'

The reason why [IndexNumber] is not an identity column is that it must be editable.


回答1:


Another alternative, if you don't want to split the code into separate batches, is to use EXEC to create a nested scope/batch:

Print 'Beginning Upgrade'
Begin Transaction
    -- --------------------------------------------------------------------
    USE [MyDatabase];

    /* Widgets now can be ordered and the order can be modified */
    ALTER TABLE [dbo].[Widgets] ADD [IndexNumber] [int] NULL;

    EXEC('DECLARE @ind INT 
    SET @ind = 0 
    UPDATE [dbo].[Widgets]
    SET @ind = [IndexNumber] = @ind + 1;');

    ALTER TABLE [dbo].[Widgets] ALTER COLUMN [IndexNumber] [int] NOT NULL;
    -- --------------------------------------------------------------------
Commit tran
Print 'Upgrade completed'

The reason why the original code doesn't work because it tries to compile the entire batch before running it - the compilation fails and so it never even starts the transaction, let along alters the table.




回答2:


You cannot add a new column and use it within the same batch. You need to insert GO between adding a column and using it.

Transaction is still ok (you can test that by changing Commit tran to rollback tran to see no changes were committed).

Print 'Beginning Upgrade'
Begin Transaction
    -- --------------------------------------------------------------------
    USE [MyDatabase];

    /* Widgets now can be ordered and the order can be modified */
    ALTER TABLE [dbo].[Widgets] ADD [IndexNumber] [int] NULL;

    GO

    DECLARE @ind INT 
    SET @ind = 0 
    UPDATE [dbo].[Widgets]
    SET @ind = [IndexNumber] = @ind + 1;

    ALTER TABLE [dbo].[Widgets] ALTER COLUMN [IndexNumber] [int] NOT NULL;
    -- --------------------------------------------------------------------
Commit tran
Print 'Upgrade completed'



回答3:


Call 'go' after you alter table

USE [MyDatabase];

  /* Widgets now can be ordered and the order can be modified */
  ALTER TABLE [dbo].[Widgets] ADD [IndexNumber] [int] NULL;
GO

BEGIN TRAN;
    DECLARE @ind INT 
    SET @ind = 0 
    UPDATE [dbo].[Widgets]
    SET @ind = [IndexNumber] = @ind + 1;

    ALTER TABLE [dbo].[Widgets] ALTER COLUMN [IndexNumber] [int] NOT NULL;
    -- --------------------------------------------------------------------
COMMIT TRAN;


来源:https://stackoverflow.com/questions/23494058/create-column-and-insert-into-it-within-the-same-transaction

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!