【问题标题】:Can I create a named default constraint in an add column statement in SQL Server?我可以在 SQL Server 的添加列语句中创建命名默认约束吗?
【发布时间】:2011-04-15 18:18:04
【问题描述】:

在 SQL Server 中,我在表上有一个新列:

ALTER TABLE t_tableName 
    ADD newColumn NOT NULL

这失败了,因为我在没有指定默认约束的情况下指定了 NOT NULL。该表不应有默认约束。

为了解决这个问题,我可以使用默认约束创建表,然后将其删除。

但是,似乎没有任何方法可以指定默认约束应命名为该语句的一部分,所以我摆脱它的唯一方法是有一个存储过程在sys.default_constraints 表。

对于一个可能经常发生的操作来说,这有点混乱/冗长。有没有人对此有更好的解决方案?

【问题讨论】:

    标签: sql-server constraints alter-table code-maintainability


    【解决方案1】:

    这应该可行:

    ALTER TABLE t_tableName 
        ADD newColumn VARCHAR(50)
        CONSTRAINT YourContraintName DEFAULT '' NOT NULL
    

    【讨论】:

    • 也适用于 2012 年。血腥细节:msdn.microsoft.com/en-us/library/ms187742.aspx
    • 为什么不把NOT NULL放在数据类型旁边呢?把它放在约束之后可能在语法上是有效的,但是把它放在那里似乎很混乱。
    • @Tullo_x86 SSMS 和 SSDT 中的“生成脚本...”工具仍默认将 NOT NULL 部分放在类型、默认约束和临时表之后的行尾GENERATED 位。太可怕了。
    【解决方案2】:
    ALTER TABLE t_tableName 
        ADD newColumn int NOT NULL
            CONSTRAINT DF_defaultvalue DEFAULT (1)
    

    【讨论】:

    • 我更喜欢这个而不是接受的答案,因为我可以放弃默认约束而不必担心丢失 NOT NULL 约束。
    • @EleventhDoctor 这没有任何意义。 NOT NULL 不是约束的一部分,drop 语句只引用约束名称
    • @RogerWillcocks 你是对的,但阅读后更清楚的是 NOT NULL 与约束是分开的。
    【解决方案3】:

    我想补充一些细节:

    最重要的提示是:永远不要在没有明确名称的情况下创建约束!

    未命名约束的最大问题:当您在各种客户机器上执行此操作时,您会在每台机器上获得不同/随机名称
    任何未来的升级脚本都会让人头疼...

    一般建议是:

    • 没有名称就没有约束!
    • 使用一些命名约定,例如
      • DF_TableName_ColumnName 用于默认约束
      • CK_TableName_ColumnName 用于检查约束
      • UQ_TableName_ColumnName 用于唯一约束
      • PK_TableName 用于主键约束

    一般语法是

    TheColumn <DataType> Nullability CONSTRAINT ConstraintName <ConstraintType> <ConstraintDetails>
    

    在这里试试

    您可以为每列添加更多约束,并且可以像在逗号后添加列一样添加其他约束:

    CREATE TABLE dbo.SomeOtherTable(TheIdThere INT NOT NULL CONSTRAINT PK_SomeOtherTable PRIMARY KEY)
    GO
    CREATE TABLE dbo.TestTable
    (
     --define the primary key
     ID INT IDENTITY NOT NULL CONSTRAINT PK_TestTable PRIMARY KEY
    
     --let the string be unique (results in a unique index implicitly)
    ,SomeUniqueString VARCHAR(100) NOT NULL CONSTRAINT UQ_TestTable_SomeUniqueString UNIQUE
    
     --define two constraints, one for a default value and one for a value check
    ,SomeNumber INT NULL CONSTRAINT DF_TestTable_SomeNumber DEFAULT (0)
                         CONSTRAINT CK_TestTable_SomeNumber_gt100 CHECK(SomeNumber>100)
    
     --add a foreign key constraint
    ,SomeFK INT NOT NULL CONSTRAINT FK_TestTable_SomeFK FOREIGN KEY REFERENCES dbo.SomeOtherTable(TheIdThere)
    
     --add a constraint for two columns separately
    ,CONSTRAINT UQ_TestTable_StringAndNumber UNIQUE(SomeFK,SomeNumber)
    );
    GO
    

    --插入一些数据

    INSERT INTO dbo.SomeOtherTable VALUES(1);
    INSERT INTO dbo.TestTable(SomeUniqueString,SomeNumber,SomeFK) VALUES('hello',111,1);
    GO
    INSERT INTO dbo.TestTable(SomeUniqueString,SomeNumber,SomeFK) 
    VALUES('fails due to uniqueness of 111,1',111,1);
    

    【讨论】:

    • 前 2 个答案都命名了它们的约束,所以你的陈述“我想添加一些细节,因为现有的答案相当薄:最重要的提示是:你永远不应该创建一个没有明确名称的约束!” - 似乎有些多余。
    【解决方案4】:

    试试下面的脚本-

    ALTER TABLE DEMO_TABLE
    ADD Column1 INT CONSTRAINT Def_Column1 DEFAULT(3) NOT NULL,
        Column2 VARCHAR(10) CONSTRAINT Def_Column2 DEFAULT('New') NOT NULL;
    GO
    

    【讨论】:

      【解决方案5】:

      我在向大表添加新列和默认值时使用以下内容。 分别执行每一行:

      ALTER TABLE dbo.[TableName] ADD [ColumnName] BIT NULL; /*null>no table rebuild*/
      
      UPDATE rf SET rf.[ColumnName] = 0 FROM dbo.[TableName] rf WHERE rf.[ColumnName] IS NULL;
      
      ALTER TABLE dbo.[TableName] ALTER COLUMN [ColumnName] BIT NOT NULL;
      
      ALTER TABLE dbo.[TableName] ADD CONSTRAINT DF_[TableName]_[ColumnName] DEFAULT 0 FOR [ColumnName];
      

      【讨论】:

        猜你喜欢
        • 2021-08-31
        • 1970-01-01
        • 1970-01-01
        • 2013-01-08
        • 1970-01-01
        • 1970-01-01
        • 2011-05-17
        • 2020-12-11
        相关资源
        最近更新 更多