如何更改SQL Server中列的默认值

如何更改SQL Server中列的默认值,sql,database,sql-server-2008,Sql,Database,Sql Server 2008,假设我有一个名为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' ) IF not ex

假设我有一个名为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'
)
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
如何使用sql查询删除该列的默认值?此外,如果一开始它不存在,我如何添加它。 我知道可以通过修改表和在P_Id列上添加约束来添加它,但我不确定这是否是唯一的方法。然而,我遇到过这样的情况,即建议中的方法似乎并不奏效

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

有什么想法吗

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

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
不过,对于
ALTER
,我不知道有什么简单的方法可以做到这一点。在您的情况下,如果默认约束不在该列上,我会说:

ALTER TABLE dbo.Persons ADD CONSTRAINT dfCity DEFAULT ('Sandnes') FOR City;
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
这只是因为我已经知道向表中添加约束的语法,因为我已经做了很多了。这篇文章有点过时,但它可能会很有用,因为它的大部分内容仍然是相关的,并且在新特性方面也没有太多遗漏:

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

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
当然还有在线图书中的
ALTER TABLE
主题:

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

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
如果要删除约束,首先需要找到名称,然后可以说:

ALTER TABLE dbo.Persons DROP CONSTRAINT constraint_name;
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

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

您可以使用
sys.default\u 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;
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

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

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
基于此示例表:

CREATE TABLE MyTable
 (
   MyTableId  int          not null
  ,SomeData   varchar(50)  not null  default 'Foo'
  ,MoreData   datetime     not null  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
步骤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 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
试试看,你会发现生成的名字基本上是随机的。要确定列上是否存在默认值,可以执行以下操作:

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'
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
要删除不知道名称的现有默认值,必须构建动态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
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
(通过错误检查,检查表和列的参数,等等。)

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
最后,通过在创建约束时命名默认值,可以避免大多数情况,如下所示:

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
或者像这样:

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

您肯定要修改表,因为这是修改表结构的唯一方法。哪一列?您有两个默认列。方法是一样的,只是要确保显式示例处理的是您所讨论的列。这种语法也不起作用。调用
sp\u executesql
时无法生成命令,需要先生成命令。你试过了吗?另外,
varchar(max)
,真的吗?编辑了它。128码是从另一个问题得到的提示,所以这个问题仍然不起作用。强烈建议在发布之前尝试您的代码
sp_executesql
需要一个
nvarchar
命令。谢谢。这正是我一直在寻找的。感谢您的仔细解释。显然,我花了太多时间修复未命名的默认值。另请参阅