2010-02-15 71 views
39

我已经有一张由数据组成的表格。我需要修改表格以添加两个不为空的新列。我该如何做,而不会丢失任何现有的数据?将不可为空的列添加到SQL Server中的现有表中?


这里就是我试图(通过右键单击表并选择设计):

  1. 增加了新的栏目 'EmpFlag'(位,空), 'CreatedDate'(日期时间, 空)

  2. 更新表中的'EmpFlag'列,以获得一些有效值。 (只想在一个领域工作,所以我没有更新'CreatedDate'字段)

  3. 现在右键单击表,设计,并使其不为空。

当我试图保存,此错误消息出现了:

保存更改是不允许的。 您所做的更改要求 下列表格被删除并重新创建

+0

我认为这是SSMS设计工具的限制。试着用SQL语句来做:“alter table tablename alter column empFlag bit not null”。用这个运行一个新的查询,然后用真实名称更改表名。 – 2010-02-15 21:21:59

+5

这与您所做更改的细节没有多大关系,而是反映了SSMS中的新默认行为 - 防止人们在不知不觉中对大型生产表进行灾难性更改,这些更改会在复制所需时间基本上使其脱机数据并重新填充表格。您可以关闭此工具工具>选项>设计器>表格+数据库设计师>防止保存更改...(取消选中此项)。但要对生产表进行这些更改时要非常小心。 – 2010-02-19 21:45:12

回答

60

您只需在新列中设置一个默认值,并允许您添加它们。

alter table table_name 
    add column_name datetime not null 
     constraint DF_Default_Object_Name default (getdate()) 

or this this for a varchar field。

alter table table_name 
    add column_name varchar(10) not null 
     constraint DF_Default_Object_Name default ('A') 

如果在添加列后不需要它,也可以删除默认值。

alter table table_name 
    drop constraint DF_Default_Object_Name 
+0

这个答案是正确的。 – mwigdahl 2010-02-15 19:54:41

+0

你应该提供一些示例代码 – Manu 2010-02-15 19:54:41

+2

请注意,如果你有一个100%的填充因子(默认),那么将数据添加到像这样的所有行将导致一堆页面拆分。这是很多I/O,我相信这是一个阻塞操作。这在一张中等大小的桌子上很好,但如果你有一个大而高的吞吐量表,它基本上是一个离线操作。据我所知,将其作为“在线”操作的唯一方法是创建一个具有所需结构的新表格;合并数据与触发器和批处理操作;最后在一次交易中交换新表(同义词工作良好) – ahains 2010-02-16 20:43:03

20

如果你不想把默认的列,您可以:

  1. 创建新列可为空
  2. 更新现有的数据适当
  3. 添加NOT NULL约束
+1

我更喜欢这种方法来定义默认... – gbn 2010-02-15 20:15:23

+0

总的来说,我同意,但它取决于场景。如果要添加像CreatedDate和ModifiedDate这样的列,则可以应用默认值,然后返回并根据需要调整旧数据,那么不必担心2和2之间的任何停机时间(或插入新行) 3.在标准默认值有意义的情况下,这使您可以灵活地不同步所有尚不知道新列的代码。 – 2010-02-15 20:23:52

+0

这对于步骤3 - [更改列:null为非空](https://stackoverflow.com/q/689746/188926)非常有用 – Dunc 2017-06-26 11:07:36

0

添加新的NOT NULL列与默认值可以在下面的GUI中完成。将现有的更改为NOT NULL似乎是另一回事。我收到了同样的信息。一种选择是创建一个新的NOT NULL列,并使用默认值替换旧列,然后将旧列数据复制到新列数据。在设计视图

  1. 认沽表(右键点击表 - >选择设计
  2. 添加列,选择数据类型
  3. 取消选中允许空并设置默认值或绑定 =您的默认值像下面

enter image description here

相关问题