【问题标题】:How to change the default value of a column in SQL Server如何更改 SQL Server 中列的默认值
【发布时间】:2012-03-25 02:18:11
【问题描述】:

假设我有一个名为 Person 的表定义如下:

CREATE TABLE Persons
(
    P_Id uniqueidentifier Default newsequentialid() NOT NULL,
    LastName varchar(255) NOT NULL,
    FirstName varchar(255),
    Address varchar(255),
    City varchar(255) DEFAULT 'Sandnes'
)

如何使用 sql 查询删除该列的默认值?此外,如果它一开始不存在,我该如何添加它。 我知道可以通过更改表并在 P_Id 列上添加约束来添加它,但我不确定这是否是唯一的方法。我遇到过this article,但是那里的建议似乎并没有真正起作用。

有什么想法吗?

【问题讨论】:

  • 你肯定会去ALTER你的桌子,因为这是修改其结构的唯一方法。
  • 哪一栏?您有两列具有默认值。方法将是相同的,只是想确保明确的示例正在处理您正在谈论的列。

标签: sql database sql-server-2008


【解决方案1】:

在 SQL Server 中,默认值定义为与表中特定列关联的约束。所有约束都有一个名称;这很重要,因为一旦创建了约束,如果你想修改它,你必须用这个名字来引用它。 (我会关注这个问题,看看我是不是错了。)

基于此示例表:

CREATE TABLE MyTable
 (
   MyTableId  int          not null
  ,SomeData   varchar(50)  not null  default 'Foo'
  ,MoreData   datetime     not null  default CURRENT_TIMESTAMP
 )

第 1 步:确定列上是否存在约束。有几种方法可以做到这一点,都涉及系统视图和/或元数据功能。这是一个快速的,可以将“MyTable”和“SomeData”设置为参数:

SELECT name
 from sys.default_constraints
 where parent_object_id = object_id('MyTable')
  and parent_column_id = columnproperty(object_id('MyTable'), 'SomeData', 'ColumnId')

试一试,您会发现生成的名称本质上是随机的废话。要确定列上是否存在默认值,您可以这样做:

IF exists (select name
            from sys.default_constraints
            where parent_object_id = object_id('MyTable')
             and parent_column_id = columnproperty(object_id('MyTable'), 'SomeData', 'ColumnId'))
    PRINT 'Default found'
ELSE
    PRINT 'NoDefault'

要删除您不知道名称的现有默认值,您必须构建动态 SQL。 (引用文章中的代码是错误的,显然从未测试过。)@Călin 的做法与我的做法略有不同,但想法是一样的:

DECLARE @Command nvarchar(max)

SELECT @Command = 'ALTER TABLE MyTable drop constraint ' + name
 from sys.default_constraints
 where parent_object_id = object_id('MyTable')
  and parent_column_id = columnproperty(object_id('MyTable'), 'SomeData', 'ColumnId')

IF @Command is not null
    EXECUTE sp_executeSQL @Command

(带有错误检查,正在检查的表和列的参数等等。)

最后,您可以通过在创建约束时命名默认值来避免大部分情况,如下所示:

CREATE TABLE MyTable
 (
   MyTableId  int          not null
  ,SomeData   varchar(50)  not null
    constraint DF_MyTable__SomeData  default 'Foo'
  ,MoreData   datetime     not null
    constraint DF_MyTable__MoreData  default CURRENT_TIMESTAMP
 )

或者像这样:

IF not exists (select name
                from sys.default_constraints
                where parent_object_id = object_id('MyTable')
                 and parent_column_id = columnproperty(object_id('MyTable'), 'SomeData', 'ColumnId'))
    ALTER TABLE MyTable
     add constraint DF_MyTable__SomeData
      default 'Foo' for SomeData

【讨论】:

【解决方案2】:

找出已存在表的语法的最简单方法是右键单击对象资源管理器中的表并选择Script As > Create To > New Window。如果您需要创建一个类似的表,这将帮助您生成脚本。

不过,我不知道为ALTER 执行此操作的简单方法。在您的情况下,如果该默认约束不在该列上,我会说:

ALTER TABLE dbo.Persons ADD CONSTRAINT dfCity DEFAULT ('Sandnes') FOR City;

这只是因为我已经知道将约束添加到表的语法,因为我不得不做很多事情。这篇文章有点过时了,但它可能很有用,因为其中大部分内容仍然相关,并且在新功能方面并没有遗漏太多:

Working with Default Constraints

当然还有在线图书中的ALTER TABLE 主题:

http://msdn.microsoft.com/en-us/library/ms190273.aspx

如果你想去掉约束,你首先需要找到名字然后你可以说:

ALTER TABLE dbo.Persons DROP CONSTRAINT constraint_name;

@Calin 发布了一个获取约束名称的查询,但我认为您不能通过这种方式将 @constraintname 传递给 ALTER TABLE 语句。

【讨论】:

    【解决方案3】:

    您可以使用sys.default_constraints 上的查询来获取默认约束的名称,然后通过更改您的表来删除它:

    declare @constraintname varchar(128);
    select @constraintname = d.name
    from sys.default_constraints d
    join sys.columns c ON c.column_id = d.parent_column_id AND c.object_id = d.parent_object_id
    join sys.objects o ON o.object_id = d.parent_object_id
    WHERE o.name = 'Persons' AND c.name = 'P_Id';
    
    declare @sql nvarchar(256);
    set @sql = 'ALTER TABLE Persons DROP CONSTRAINT ' + @constraintName;
    EXEC sp_executesql @sql;
    

    【讨论】:

    • 这种语法也不起作用。调用sp_executesql时无法构建命令,需要先构建命令。你试过了吗?另外,varchar(max),真的吗?
    • 已编辑。 128 大小是从另一个 SO 问题stackoverflow.com/questions/5808332/… 中得到的提示
    • 还是不行。强烈建议在发布之前尝试您的代码。 sp_executesql 需要 nvarchar 命令。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-18
    • 1970-01-01
    • 2011-04-14
    • 2012-07-03
    相关资源
    最近更新 更多