如何更新SQL表中的计算列

时间:2019-02-08 01:30:58

标签: sql-server performance tsql

我有一个带有计算列的表,如下所示(请参见IsFlag列)

CREATE TABLE [TableName]
(
    [ID] [INT] IDENTITY(1,1) NOT NULL,
    [IsFlag1] [BIT] NOT NULL,
    [IsFlag2] [BIT] NOT NULL,
    [IsFlag3] [BIT] NOT NULL,
    [IsFlag] AS (CASE WHEN [IsFlag1] = (1) OR [IsFlag2] = (1) OR [IsFlag3] = (1) THEN (1) ELSE (0) END)
)

一些索引和视图引用了计算列。

现在,我需要向表中添加另一个标志[IsFlag4] [BIT] NOT NULL并将计算的列更新为

[IsFlag] AS (CASE WHEN [IsFlag1] = (1) OR [IsFlag2] = (1) OR 
                       [IsFlag3] = (1) OR [IsFlag4] = (1) 
                  THEN (1) ELSE (0) END)

该表包含大量数据,并删除和创建所有索引,因此需要关注视图

在使停机时间最短的情况下实施此更改有什么选择?

谢谢

1 个答案:

答案 0 :(得分:2)

这是计算列,不占用空间(除非指定为PERSISTED

因此,在添加“ IsFlag4”之后,使用新的计算再次将其添加。

使用临时表的示例:

IF OBJECT_ID('tempdb..#TableName', 'U') IS NOT NULL DROP TABLE #TableName; 
CREATE TABLE #TableName
(
    [ID] [INT] PRIMARY KEY IDENTITY(1,1) NOT NULL,
    [IsFlag1] [BIT] NOT NULL DEFAULT 0,
    [IsFlag2] [BIT] NOT NULL DEFAULT 0,
    [IsFlag3] [BIT] NOT NULL DEFAULT 0,
    [IsFlag] AS (CASE WHEN [IsFlag1] = 1 OR [IsFlag2] = 1 OR [IsFlag3] = 1 THEN 1 ELSE 0 END)
);

CREATE INDEX idx_TableName_IsFlag ON #TableName ([IsFlag]);  

insert into #TableName (IsFlag1, IsFlag2, IsFlag3) values (0,0,0),(0,0,1);

-- Add [IsFlag4]
ALTER TABLE #TableName ADD [IsFlag4] [BIT] NOT NULL DEFAULT 0;

-- Drop and Add [IsFlag]
-- Drop index first, and add it again after
BEGIN
  DROP INDEX idx_TableName_IsFlag ON #TableName;
  ALTER TABLE #TableName DROP COLUMN [IsFlag];
  ALTER TABLE #TableName ADD [IsFlag] AS ([IsFlag1] | [IsFlag2] | [IsFlag3] | [IsFlag4]);
  CREATE INDEX idx_TableName_IsFlag ON #TableName ([IsFlag]);
END;

insert into #TableName (IsFlag1, IsFlag2, IsFlag3, IsFlag4) values (0,0,0,1);

select * from #TableName;

返回:

ID  IsFlag1 IsFlag2 IsFlag3 IsFlag4 IsFlag
1   0       0       0       0       0
2   0       0       1       0       1
3   0       0       0       1       1