如何将默认为日期时间的小日期时间列更改为日期时间?

发布于 2024-08-14 16:34:36 字数 964 浏览 4 评论 0原文

我的数据库中有许多列最初创建为 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 是什么时,我才能编写该脚本,因为我无法删除约束中引用的列。

这真的有那么难吗?

I have a number of columns in my database that were originally created as smalldatetime and that really need to be datetime. Many of these columns were created with the DDL:

[columnname] smalldatetime not null default getdate()

...which means that in order to alter the column's type, I first have to drop the default, and then re-create the default after altering it.

Of course, I didn't specify a name for the default in the DDL, so the columns all have defaults with names like DF__CaseLock__CaseCo__182C9B23. And when my application creates its database, it does so by executing a script, so the names of the defaults in my customers' databases are (I'm guessing; I haven't verified this) different from their names in mine.

And even if I know the name of the default constraint, I can't figure out the syntax for adding it back in after I drop it. In fact, it's not clear to me that it's possible to add a default constraint to an existing column.

It appears that what I have to do is something like this:

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

...only I can only write that script if I know what constraint_name is, because I can't drop a column that's referenced in a constraint.

Is this really that hard?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

霞映澄塘 2024-08-21 16:34:36

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

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

您可以询问 sys 表以查找现有约束。当您重新添加它们时,您应该为它们提供一个明确的名称。 这是一篇博客文章,其中有一个数字用于处理删除/添加未命名约束的脚本。希望有帮助!

You can add a default constraint like this:

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

You can interrogate the sys tables to find the existing constraints. When you add them back in, you should provide an explicit name for them. Here's a blog post that has a number of scripts for dealing with dropping/adding unnamed constraints. Hope that helps!

颜漓半夏 2024-08-21 16:34:36

恐怕你必须求助于动态 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

I'm afraid you have to resort to dynamic SQL.

Bear in mind though that any data that was previously set by the old default will remain.

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

EDIT: Where multiple default columns exist in 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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文