从一个表格批量插入到另一个表格,且全部在服务器端完成。

5
我需要将一些数据从一个数据库表复制到另一个数据库表中。由于其中一个列是标识列,因此我无法使用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. 将一个表分成两个新表。将来每个表都将有自己的标识列,但为了迁移,我认为使用原始表的标识作为两个新表的标识最简单。迁移结束后,其中一个表将与另一个表存在一对多关系。 2. 将某些列从一个表移到另一个表。 3. 删除一些只进行1对1交叉引用的交叉引用表。代替方法是在两个表中的一个中使用外键引用。 4. 创建带有默认值的新列。 5. 有些表根本不会改变,但由于“将所有内容放入新数据库”的要求,我必须将它们复制过来。
4个回答

3

有没有办法在批量插入技术中使用Identity_insert?普通的插入(INSERT INTO ... SELECT)对我的目的来说太慢了。 - stannius

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服务器上进行其他操作。
一个好处是,您可以在本地或测试服务器上测试此脚本,并且可以通过重新运行脚本重复执行它。
您的架构更改是否过于复杂,无法通过脚本进行更改?

你能举一个结合SELECT...INTO和IDENTITY_INSERT的插入示例吗? - stannius

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

0

由于有很多人查看这个问题,我想我应该进行跟进。

最终,我选择使用SSIS包。我在数据库服务器本身上执行它。它仍然经历了从SQL进程到SSIS进程的数据提取过程,然后将其发送回去的繁琐流程。但总体而言,它比我调查的其他选项执行得更快。

此外,我遇到了一个错误:从视图中提取数据时,程序包会挂起。最终,我将视图中的查询从源对象的“SQL查询”字段中剪切并粘贴到SSIS中。只有当程序包在同一台机器上运行时,才会出现这种情况。当从另一台机器运行时,我没有遇到这个错误。

如果我必须重新做一遍,我可能会生成新的身份值。我会将旧值迁移到新表的列中,使用这些值来关联其他表的外键,然后在迁移完成且稳定之后删除该列。另一方面,总体而言,SSIS包方法运行正常,因此如果您需要进行复杂的迁移(如拆分表等)或需要保持身份值不变,则我建议使用它。

感谢所有回答的人。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接