2012-03-07 144 views
1

按说我已经定义了这样一个名为Person表:如何更改列的缺省值在SQL Server

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但是,有人建议,似乎并没有真正的工作。

任何想法?

+0

你肯定会'ALTER'你的桌子,因为它是修改其结构的唯一方法。 – 2012-03-07 14:41:10

+0

哪一列?你有两列有默认值。该方法将是相同的,只是想确保明确的例子正在处理你正在谈论的专栏。 – 2012-03-07 14:53:58

回答

4

在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。 (引用的文章中的代码是错误的,并明确从来没有测试。)@ CALIN确实稍微不同于我会做到这一点,但这个想法是一样的:

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 
+0

谢谢。这正是我正在寻找的。感谢您的详细解释。 – ScorpiAS 2012-03-07 15:19:07

+1

显然,我花了太多的时间修复未命名的默认值。 – 2012-03-07 15:22:01

+0

另请参阅http://stackoverflow.com/questions/1397440/what-is-the-purpose-of-constraint-naming/1397493#1397493 – 2012-03-07 15:23:37

4

找出已存在的表的语法的最简单方法是右键单击对象资源管理器中的表并选择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发布了一个可以得到约束名称的查询,但我不认为你可以这样通过@constraintnameALTER TABLE

+0

太棒了。它的工作..有帮助 – 2016-07-18 09:09:17

0

你可以使用上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; 
+0

这种语法也不起作用。调用'sp_executesql'时无法生成命令,您需要先构建命令。你试过了吗?另外,'varchar(max)',真的吗? – 2012-03-07 14:57:01

+0

编辑它。 128大小是从另一个SO问题提示 http://stackoverflow.com/questions/5808332/sql-server-maximum-character-length-of-object-names – 2012-03-07 15:22:12

+0

仍然无法正常工作。强烈建议在发布之前尝试您的代码。 'sp_executesql'需要'nvarchar'命令。 – 2012-03-07 15:23:28