我必须将一堆数据从一个数据库表复制到另一个数据库表中。我不能使用SELECT ... INTO,因为其中一列是标识列。此外,我对架构进行了一些更改。我能够使用导出数据向导来创建一个SSIS包,然后我在Visual Studio 2005中对其进行编辑以进行所需的更改。它肯定比INSERT INTO更快,但是将数据下载到另一台计算机只是为了再次上传它似乎很愚蠢。 (假设我是正确的,这就是SSIS包正在做的事情)。是否存在直接在服务器上运行的BULK INSERT,允许保留标识值以及从表中提取数据? (据我所知,BULK INSERT只能从文件中提取数据)
编辑: 我知道IDENTITY_INSERT,但因为涉及到相当多的数据,INSERT INTO ... SELECT有点慢。 SSIS / BULK INSERT将数据转储到表中,而不考虑索引和日志记录等等,因此速度更快。 (当然,一旦填充后在表上创建聚簇索引并不快,但它仍然比我在第一次尝试时尝试的INSERT INTO ... SELECT更快)
编辑2: 架构更改包括(但不限于)以下内容: 1.将一个表拆分为两个新表。将来每个都有自己的IDENTITY列,但是对于迁移,我认为最简单的方法是使用原始表中的标识作为两个新表的标识。迁移完成后,其中一个表将与另一个表具有一对多关系。 2.将列从一个表移动到另一个表。 3.删除一些仅交叉引用1对1的交叉引用表。相反,引用将是两个表之一中的外键。 4.将使用默认值创建一些新列。 5.有些表根本没有变化,但由于“全部放入新数据库”请求,我必须复制它们。
答案 0 :(得分:3)
我想您可能对Identity Insert
感兴趣答案 1 :(得分:2)
我认为SELECT ... INTO应该与IDENTITY列一起使用。您可能需要重新定义主键:
SELECT * INTO NewTable FROM OldTable
GO
ALTER TABLE NewTable ADD PRIMARY KEY(ColumnName)
如果这不起作用,您可以为旧表生成CREATE TABLE脚本,更改名称以创建新表,然后使用IDENTITY_INSERT允许从第一个表复制主键数据使用INSERT INTO NewTable SELECT FROM OLDTABLE。然后,您可以在SQL中对服务器执行其他操作。
一个很好的好处是你可以在本地或在测试服务器上测试这个脚本,如果只需要重新运行脚本就可以重复它。
您的架构是否变得太复杂,无法通过脚本进行更改?
答案 2 :(得分:1)
请查看,
Select * Into NewTable
From OldTable
Where 1=2
Alter Table NewTable
Add id_col int indentity(1,1)
insert into NewTable(col1,col2,..... )
/* do not use id_col */
select col1,col2,..... from OldTable
答案 3 :(得分:0)
由于有这么多人看过这个问题,我想我应该跟进。
我最终坚持使用SSIS包。我在数据库服务器上执行它。它仍然经历了将数据从sql进程提取到SSIS进程然后将其发送回来的严峻考验。但总的来说,它比我调查的其他选项执行得更快。
此外,我遇到了一个错误:从视图中提取数据时,包只会挂起。我最终将查询中的查询直接剪切并粘贴到SSIS中“源”对象的“sql查询”字段中。当程序包与服务器在同一台机器上运行时,似乎只会发生这种情况。当从另一台机器运行时,我没有遇到这个错误。
如果我不得不重新做一遍,我可能会生成新的身份值。我会将旧的列迁移到新表中的列,使用这些值来关联其他表的外键,然后在迁移完成并稳定后删除列。另一方面,总的来说SSIS包方法工作正常,所以如果你必须进行复杂的迁移(拆分表等)或者需要保持身份值不变,我会推荐它。
感谢所有回复的人。