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
要确保在UPDATE
和ALTER COLUMN
语句之间没有插入新行,需要哪种锁定/事务隔离级别?这是为了防止由于新插入的行中ALTER COLUMN
中的NULL
值而导致MyColumn
语句失败。
是否有更好的替代方法GO
,以确保ADD [MyColumn]
在SET [MyColumn]
之前完成?
答案 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