Sql server 添加列时保留表的数据

Sql server 添加列时保留表的数据,sql-server,tsql,database-design,Sql Server,Tsql,Database Design,我需要添加一列[new_date],我将从我的[date]sql表中获取该列,并将其添加到现有表[returns]中,然后创建主键。这个[返回]表已经有6500万条记录,而我可以重新填充所有数据。最简单的方法是什么 我的想法是用一个临时名称重命名这个表。说[returns_old],然后删除并创建我的新表,并分配我的主键。我认为,在填充新表时,将[returns_old]与[d_date]连接起来是可行的。假设您不关心列的顺序,因为使用视图可以更容易地管理列顺序,那么这种方法实际上可以归结为列本

我需要添加一列[new_date],我将从我的[date]sql表中获取该列,并将其添加到现有表[returns]中,然后创建主键。这个[返回]表已经有6500万条记录,而我可以重新填充所有数据。最简单的方法是什么


我的想法是用一个临时名称重命名这个表。说[returns_old],然后删除并创建我的新表,并分配我的主键。我认为,在填充新表时,将[returns_old]与[d_date]连接起来是可行的。

假设您不关心列的顺序,因为使用视图可以更容易地管理列顺序,那么这种方法实际上可以归结为列本身是否可以为空

如果该列可以为null,则只需一条简单语句即可将该列追加到表中。该列的所有记录都将
NULL
,直到您从源表中更新它们为止

ALTER TABLE [returns] ADD [new_date] DATETIME
如果列不能为null,则需要添加更多步骤

ALTER TABLE [returns] ADD [new_date] DATETIME
GO
-- Update all existing records so that no existing value is NULL
ALTER TABLE [returns] ALTER COLUMN [new_date] DATETIME NOT NULL
如果列顺序对您有影响,我会重新考虑是否可能(这样做有很多原因)。原因如下:

  • 如果不重新构建整个表,这是不可能的——这是一个非常昂贵的步骤
  • 没有性能优势(如有必要,构建索引)
  • 没有存储好处()

假设您不关心列的顺序,因为使用视图可以更轻松地管理列顺序,那么这种方法实际上可以归结为列本身是否可以为空

如果该列可以为null,则只需一条简单语句即可将该列追加到表中。该列的所有记录都将
NULL
,直到您从源表中更新它们为止

ALTER TABLE [returns] ADD [new_date] DATETIME
如果列不能为null,则需要添加更多步骤

ALTER TABLE [returns] ADD [new_date] DATETIME
GO
-- Update all existing records so that no existing value is NULL
ALTER TABLE [returns] ALTER COLUMN [new_date] DATETIME NOT NULL
如果列顺序对您有影响,我会重新考虑是否可能(这样做有很多原因)。原因如下:

  • 如果不重新构建整个表,这是不可能的——这是一个非常昂贵的步骤
  • 没有性能优势(如有必要,构建索引)
  • 没有存储好处()

您应该首先添加一个新的空列,因为这是一个现有表

ALTER TABLE [returns] ADD [new_date] DateTime NULL 

一旦有了新列,就可以使用update语句从另一个表中更新date列。

您应该首先添加一个新的空列,因为这是一个现有表

ALTER TABLE [returns] ADD [new_date] DateTime NULL 

拥有新列后,可以使用update语句从另一个表中更新date列。

在事务中执行此操作:

create table dbo.ReturnsTemp ( keyfield type, new_date datetime, field2 type, field3 type);   

alter table dbo.ReturnsTemp add constraint NewPKName primary key (keyfield, new_date);

begin tran
    insert into dbo.[ReturnsTemp] ( keyfield , field2, field3, new_date )
    select r.keyfield , r.field2, r.field3, d.[new_date]
      from dbo.[Returns] r     
     inner join dbo.[DateTable] d on r.keyfield = r.keyfield

    exec sp_rename 'Returns', 'Returns_Old'
    exec sp_rename 'ReturnsTemp', 'Returns'
end tran

根据表的大小和日志文件的大小,您可能需要谨慎使用这种方法,并确保日志文件有足够的空间容纳日志中的大量瞬态数据。可能需要先执行日志备份。

在事务中执行备份:

create table dbo.ReturnsTemp ( keyfield type, new_date datetime, field2 type, field3 type);   

alter table dbo.ReturnsTemp add constraint NewPKName primary key (keyfield, new_date);

begin tran
    insert into dbo.[ReturnsTemp] ( keyfield , field2, field3, new_date )
    select r.keyfield , r.field2, r.field3, d.[new_date]
      from dbo.[Returns] r     
     inner join dbo.[DateTable] d on r.keyfield = r.keyfield

    exec sp_rename 'Returns', 'Returns_Old'
    exec sp_rename 'ReturnsTemp', 'Returns'
end tran

根据表的大小和日志文件的大小,您可能需要谨慎使用这种方法,并确保日志文件有足够的空间容纳日志中的大量瞬态数据。可能需要先执行日志备份。

为什么需要删除表来修改它。只需执行一个
altertable添加[new_date]datetime null
,然后用另一个表中的数据回填数据。无需删除或重命名任何内容。我需要澄清,此新列将是组合主键的一部分,不可为null。您需要将该列创建为可为null的列,使用所需的值填充它,将其更改为不可为null,然后删除并重新创建PK。为什么需要删除表来修改它。只需执行一个
altertable添加[new_date]datetime null
,然后用另一个表中的数据回填数据。无需删除或重命名任何内容。我需要澄清,此新列将是组合主键的一部分,不可为null。您需要将该列创建为可为null的列,使用所需的值填充它,将其更改为不可为null,然后删除并重新创建PK。我不需要在最后提交事务吗?顺便说一句,我是一个事务迷,回滚它们节省了我几次时间。我相信开始…结束中的任何内容都会隐式提交。我不需要在结束时提交事务吗?顺便说一句,我是一个交易迷,回滚它们节省了我几次时间。我相信开始…结束中的任何内容都会被隐式提交。我尝试过几次。Stack overflow表示我没有足够的代表公开向上投票:(我尝试过几次。Stack overflow表示我没有足够的代表公开向上投票:(