如何将具有默认值的列添加到SQL Server 2000/SQL Server 2005中的现有表中?


当前回答

好吧,我现在对我之前的回答做了一些修改。我注意到,没有一个答案提到“如果不存在”。因此,我将提供一个新的解决方案,因为我在改变表格时遇到了一些问题。

IF NOT EXISTS (SELECT * FROM INFORMATION_SCHEMA.columns WHERE table_name = 'TaskSheet' AND column_name = 'IsBilledToClient')
BEGIN
ALTER TABLE dbo.TaskSheet ADD
 IsBilledToClient bit NOT NULL DEFAULT ((1))
END
GO

这里TaskSheet是特定的表名,IsBilledToClient是要插入的新列,1是默认值。这意味着在新列中现有行的值是多少,因此将在那里自动设置一个值。然而,您可以像我使用BIT一样,根据自己的意愿更改列类型,所以我输入了默认值1。

我建议采用上述系统,因为我遇到了一个问题。那么问题出在哪里呢?问题是,如果表表中确实存在IsBilledToClient列,那么如果只执行下面给出的部分代码,则SQL server查询生成器中将出现错误。但如果它不存在,那么第一次执行时将不会出现错误。

ALTER TABLE {TABLENAME}
ADD {COLUMNNAME} {TYPE} {NULL|NOT NULL}
CONSTRAINT {CONSTRAINT_NAME} DEFAULT {DEFAULT_VALUE}
[WITH VALUES]

其他回答

添加可为空的列时,WITH VALUES将确保将特定的DEFAULT值应用于现有行:

ALTER TABLE table
ADD column BIT     -- Demonstration with NULL-able column added
CONSTRAINT Constraint_name DEFAULT 0 WITH VALUES

试试这个

ALTER TABLE Product
ADD ProductID INT NOT NULL DEFAULT(1)
GO

首先创建一个名为student的表:

CREATE TABLE STUDENT (STUDENT_ID INT NOT NULL)

向其中添加一列:

ALTER TABLE STUDENT 
ADD STUDENT_NAME INT NOT NULL DEFAULT(0)

SELECT * 
FROM STUDENT

将创建表,并使用默认值将列添加到现有表中。

SQL Server+更改表+添加列+默认值uniqueidentifier

ALTER TABLE Product 
ADD ReferenceID uniqueidentifier not null 
default (cast(cast(0 as binary) as uniqueidentifier))

这有很多答案,但我觉得有必要添加这个扩展方法。这看起来要长得多,但如果要向活动数据库中有数百万行的表中添加NOT NULL字段,则非常有用。

ALTER TABLE {schemaName}.{tableName}
    ADD {columnName} {datatype} NULL
    CONSTRAINT {constraintName} DEFAULT {DefaultValue}

UPDATE {schemaName}.{tableName}
    SET {columnName} = {DefaultValue}
    WHERE {columName} IS NULL

ALTER TABLE {schemaName}.{tableName}
    ALTER COLUMN {columnName} {datatype} NOT NULL

这将做的是将列添加为可空字段,并使用默认值将所有字段更新为默认值(或者您可以分配更多有意义的值),最后将列更改为NOT NULL。

这样做的原因是,如果您更新一个大型表并添加一个新的非空字段,它必须写入每一行,因此在添加列并写入所有值时将锁定整个表。

此方法将添加可为空的列,该列本身运行速度快得多,然后在设置非空状态之前填充数据。

我发现,在一个语句中完成整个操作将在4-8分钟内锁定一个更活跃的表,而且我经常会终止这个过程。这种方法每一部分通常只需几秒钟,并导致最小的锁定。

此外,如果您有一个表,其面积为数十亿行,则可能值得按如下方式批量更新:

WHILE 1=1
BEGIN
    UPDATE TOP (1000000) {schemaName}.{tableName}
        SET {columnName} = {DefaultValue}
        WHERE {columName} IS NULL

    IF @@ROWCOUNT < 1000000
        BREAK;
END