安全地将非空列添加到现有表

时间:2020-02-12 04:19:24

标签: sql sql-server

IF NOT EXISTS(SELECT 1 FROM sys.columns 
              WHERE Name = N'MyColumn' AND Object_ID = Object_ID(N'[MySchema].[MyTable]'))
    ALTER TABLE [MySchema].[MyTable] 
        ADD [MyColumn] VARCHAR(10) NULL
GO

UPDATE [MySchema].[MyTable] 
SET [MyColumn] = 'ValueForExistingData' 
WHERE [MyColumn] IS NULL

ALTER TABLE [MySchema].[MyTable] 
    ALTER COLUMN [MyColumn] VARCHAR(10) NOT NULL

要确保在UPDATEALTER COLUMN语句之间没有插入新行,需要哪种锁定/事务隔离级别?这是为了防止由于新插入的行中ALTER COLUMN中的NULL值而导致MyColumn语句失败。

是否有更好的替代方法GO,以确保ADD [MyColumn]SET [MyColumn]之前完成?

2 个答案:

答案 0 :(得分:1)

您可以使用以下语法:

BEGIN TRANSACTION

ALTER TABLE [MySchema].[MyTable] 
        ADD [MyColumn] VARCHAR(10) NOT NULL CONSTRAINT MyTableDefault DEFAULT 'ValueForExistingData';

ALTER TABLE [MySchema].[MyTable] 
        DROP CONSTRAINT MyTableDefault;

COMMIT

在企业版SQL Server 2012+上,这两个语句将仅是元数据操作,因此您不必更新所有数据页,整个操作将花费毫秒。

答案 1 :(得分:0)

您可以设置“默认”约束,以确保所有现有列均具有现有数据的值。

然后删除默认约束,以强制新行具有输入值。

IF NOT EXISTS(SELECT 1 FROM sys.columns 
              WHERE Name = N'MyColumn' AND Object_ID = Object_ID(N'[MySchema].[MyTable]'))
    ALTER TABLE [MySchema].[MyTable] 
        ADD [MyColumn] VARCHAR(10) NOT NULL DEFAULT 'ValueForExistingData';
GO

ALTER TABLE [MySchema].[MyTable] 
ALTER COLUMN [MyColumn] DROP DEFAULT;
GO

https://docs.microsoft.com/en-us/sql/t-sql/statements/alter-table-transact-sql

相关问题