【问题标题】:Alter column, add default constraint更改列,添加默认约束
【发布时间】:2011-01-06 21:46:22
【问题描述】:

我有一张表格,其中一列是日期时间类型的“日期”。我们决定为该列添加一个默认约束

Alter table TableName
alter column dbo.TableName.Date default getutcdate() 

但这给了我错误:

'.' 附近的语法不正确

有没有人看到这里有什么明显的错误,我错过了(除了为该列取一个更好的名称)

【问题讨论】:

  • 不要使用类型或关键字作为列名!
  • 是的,同意-“有没有人在这里看到任何明显错误的地方,我错过了(除了为该列提供更好的名称)”

标签: sql-server sql-server-2008 tsql alter-table alter-column


【解决方案1】:

试试这个

alter table TableName 
 add constraint df_ConstraintNAme 
 default getutcdate() for [Date]

例子

create table bla (id int)

alter table bla add constraint dt_bla default 1 for id



insert bla default values

select * from bla

还要确保您命名默认约束。稍后删除它会让人头疼,因为它会具有那些疯狂的系统生成名称之一...另请参阅How To Name Default Constraints And How To Drop Default Constraint Without A Name In SQL Server

【讨论】:

    【解决方案2】:

    您可以将保留字用方括号括起来以避免这些类型的错误:

    dbo.TableName.[Date]
    

    【讨论】:

    • 对列名使用保留字似乎是一个非常糟糕的主意。
    • 似乎,但事实并非如此。我从 2004 年开始成功使用它们 :)
    【解决方案3】:

    我使用下面的存储过程来更新列的默认值。

    在添加新的默认值之前,它会自动删除列上的所有先前默认值。

    使用示例:

    -- Update default to be a date.
    exec [dbo].[AlterDefaultForColumn] '[dbo].[TableName]','Column','getdate()';
    -- Update default to be a number.
    exec [dbo].[AlterDefaultForColumn] '[dbo].[TableName]','Column,'6';
    -- Update default to be a string. Note extra quotes, as this is not a function.
    exec [dbo].[AlterDefaultForColumn] '[dbo].[TableName]','Column','''MyString''';
    

    存储过程:

    SET ANSI_NULLS ON
    GO
    SET QUOTED_IDENTIFIER ON
    GO
    
    -- Sample function calls:
    --exec [dbo].[AlterDefaultForColumn] '[dbo].[TableName]','ColumnName','getdate()';
    --exec [dbol].[AlterDefaultForColumn] '[dbo].[TableName]','Column,'6';
    --exec [dbo].[AlterDefaultForColumn] '[dbo].[TableName]','Column','''MyString''';
    create PROCEDURE [dbo].[ColumnDefaultUpdate]
        (
            -- Table name, including schema, e.g. '[dbo].[TableName]'
            @TABLE_NAME VARCHAR(100), 
            -- Column name, e.g. 'ColumnName'.
            @COLUMN_NAME VARCHAR(100),
            -- New default, e.g. '''MyDefault''' or 'getdate()'
            -- Note that if you want to set it to a string constant, the contents
            -- must be surrounded by extra quotes, e.g. '''MyConstant''' not 'MyConstant'
            @NEW_DEFAULT VARCHAR(100)
        )
    AS 
    BEGIN       
        -- Trim angle brackets so things work even if they are included.
        set @COLUMN_NAME = REPLACE(@COLUMN_NAME, '[', '')
        set @COLUMN_NAME = REPLACE(@COLUMN_NAME, ']', '')
    
        print 'Table name: ' + @TABLE_NAME;
        print 'Column name: ' + @COLUMN_NAME;
        DECLARE @ObjectName NVARCHAR(100)
        SELECT @ObjectName = OBJECT_NAME([default_object_id]) FROM SYS.COLUMNS
        WHERE [object_id] = OBJECT_ID(@TABLE_NAME) AND [name] = @COLUMN_NAME;
    
        IF @ObjectName <> '' 
        begin
            print 'Removed default: ' + @ObjectName;
            --print('ALTER TABLE ' + @TABLE_NAME + ' DROP CONSTRAINT ' + @ObjectName)
            EXEC('ALTER TABLE ' + @TABLE_NAME + ' DROP CONSTRAINT ' + @ObjectName)
        end
    
        EXEC('ALTER TABLE ' + @TABLE_NAME + ' ADD  DEFAULT (' + @NEW_DEFAULT + ') FOR ' + @COLUMN_NAME)
        --print('ALTER TABLE ' + @TABLE_NAME + ' ADD  DEFAULT (' + @NEW_DEFAULT + ') FOR ' + @COLUMN_NAME)
        print 'Added default of: ' + @NEW_DEFAULT;
    END
    

    此存储过程消除的错误

    如果您尝试在已经存在的列中添加默认值,您将收到以下错误(如果使用此存储过程,您将永远不会看到):

    -- Using the stored procedure eliminates this error:
    Msg 1781, Level 16, State 1, Line 1
    Column already has a DEFAULT bound to it.
    Msg 1750, Level 16, State 0, Line 1
    Could not create constraint. See previous errors.
    

    【讨论】:

      【解决方案4】:

      实际上你必须像下面的例子那样做,这将有助于解决问题......

      drop table ABC_table
      
      create table ABC_table
      (
          names varchar(20),
          age int
      )
      
      ALTER TABLE ABC_table
      ADD CONSTRAINT MyConstraintName
      DEFAULT 'This is not NULL' FOR names
      
      insert into ABC(age) values(10)
      
      select * from ABC
      

      【讨论】:

      • 这个仅供练习使用,不能实际使用
      【解决方案5】:

      您指定了两次表名。 ALTER TABLE 部分命名表。 尝试: 更改表表名 更改列 [日期] 默认 getutcdate()

      【讨论】:

        【解决方案6】:

        更改表 TableName 删除约束 DF_TableName_WhenEntered

        更改表 TableName 添加约束 DF_TableName_WhenEntered WhenEntered 的默认 getutcdate()

        【讨论】:

        • 这个答案也包含删除约束查询。如果有人之前添加了 getdate(),现在他需要将其更改为 getutcdate()。他可能会通过这个答案得到一些帮助。 @RalfFriedl
        【解决方案7】:

        我确认像 JohnH 的评论一样,永远不要在您的对象名称中使用列类型! 这很令人困惑。并尽可能使用括号。

        试试这个:

        ALTER TABLE [TableName]
        ADD  DEFAULT (getutcdate()) FOR [Date]; 
        

        【讨论】:

        • 最好还是使用"double quotes",因为那是ANSI标准。
        猜你喜欢
        • 2016-07-08
        • 1970-01-01
        • 2011-05-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多