【问题标题】:How can I alter a smalldatetime column with a default to be datetime?如何更改默认为 datetime 的 smalldatetime 列?
【发布时间】:2009-12-14 20:49:07
【问题描述】:

我的数据库中有许多列最初创建为smalldatetime,并且确实需要为datetime。其中许多列是使用 DDL 创建的:

[columnname] smalldatetime not null default getdate()

...这意味着为了更改列的类型,我首先必须删除默认值,然后在更改后重新创建默认值。

当然,我没有在 DDL 中指定默认名称,因此所有列都有默认名称,例如 DF__CaseLock__CaseCo__182C9B23。当我的应用程序创建它的数据库时,它是通过执行一个脚本来实现的,所以我客户数据库中的默认名称(我猜;我还没有验证过)与我的名称不同。

即使我知道默认约束的名称,我也无法弄清楚在删除它后将其添加回的语法。事实上,我不清楚是否可能向现有列添加默认约束。

看来我要做的是这样的:

declare @t table (id int not null primary key, date smalldatetime null)
insert into @t (id, date)
    select id, date_column from my_table
drop constraint constraint_name
alter table my_table drop column date_column;
alter table my_table add date_column datetime default getdate()
update my_table set date_column = t.date FROM my_table m JOIN @t t ON m.id = t.ID

...只有当我知道 constraint_name 是什么时,我才能编写该脚本,因为我无法删除约束中引用的列。

真的有那么难吗?

【问题讨论】:

    标签: sql-server constraints default alter


    【解决方案1】:

    您可以像这样添加默认约束:

    ALTER TABLE TableName
    ADD CONSTRAINT DF_DefaultName DEFAULT 'Default Value' FOR ColumnName
    

    您可以查询 sys 表以查找现有约束。当您重新添加它们时,您应该为它们提供一个明确的名称。 Here's a blog post 有许多用于处理删除/添加未命名约束的脚本。希望对您有所帮助!

    【讨论】:

      【解决方案2】:

      恐怕你不得不求助于动态 SQL。

      请记住,以前由旧默认设置的任何数据都将保留。

      DECLARE @query varchar(256)
      
      SET @query = (
          SELECT 'ALTER TABLE my_table DROP CONSTRAINT ' + d.name 
          FROM sysobjects d
              INNER JOIN sysobjects t ON t.id = d.parent_obj
          WHERE d.type = 'D'
              AND t.name = 'my_table')
      
      EXEC(@query)
      
      ALTER TABLE my_table
      ADD CONSTRAINT DF_date_column default getdate() for date_column
      

      编辑:my_table 中存在多个默认列:

      CREATE TABLE #Defaults (
          strName varchar(256) PRIMARY KEY
      )
      
      INSERT INTO #Defaults (strName)
      SELECT d.name 
      FROM sysobjects d
          INNER JOIN sysobjects t ON t.id = d.parent_obj
      WHERE d.type = 'D'
          AND t.name = 'my_table'
      
      DECLARE @name varchar(256), @query varchar(256)
      
      SET @name = (SELECT TOP 1 strName FROM #Defaults)
      
      WHILE @name IS NOT NULL
      BEGIN        
          SET @query = 'ALTER TABLE my_table DROP CONSTRAINT ' + @name
      
          EXEC(@query)
      
          DELETE FROM #Defaults 
          WHERE strName = @name
      
          SET @name = (SELECT TOP 1 strName FROM #Defaults)
      END
      
      ALTER TABLE my_table
      ADD CONSTRAINT DF_date_column1 default getdate() for date_column1
      
      ALTER TABLE my_table
      ADD CONSTRAINT DF_date_column2 default getdate() for date_column2
      
      DROP TABLE #Defaults
      

      【讨论】:

      • 该查询不会为my_table 上定义的每个默认约束返回一行吗?
      • 对不起,是的。我没有意识到您有多个默认约束。我马上编辑。
      猜你喜欢
      • 2012-07-03
      • 1970-01-01
      • 1970-01-01
      • 2023-03-27
      • 1970-01-01
      • 2010-12-18
      • 2011-06-12
      • 1970-01-01
      相关资源
      最近更新 更多