sql2005,我想将一个数据库1的表A的内容导入另一个数据库2的表中B,但是表A中有自增量。要怎么实现。

2024-12-23 04:18:42
推荐回答(2个)
回答1:

SQL Server 导入 IDENTITY 类型的数据。

-- 主表
CREATE TABLE test_main (
id int identity(1, 1) PRIMARY KEY,
value varchar(10)
);

-- 子表
CREATE TABLE test_sub (
id int identity(1, 1) PRIMARY KEY,
main_id INT,
value varchar(10)
);

-- 测试数据
INSERT INTO test_main
SELECT 'A' UNION ALL
SELECT 'B' UNION ALL
SELECT 'C';

INSERT INTO test_sub
SELECT 1, 'AA' UNION ALL
SELECT 2, 'BB' UNION ALL
SELECT 3, 'CC';

SELECT
test_main.value, test_sub.value
FROM
test_main JOIN test_sub ON (test_main.id = test_sub.main_id);

value value
---------- ----------
A AA
B BB
C CC

-- 删除数据,造成数据不连续
DELETE FROM test_main WHERE id = 2;
DELETE FROM test_sub WHERE main_id = 2;

再次执行前面的查询
value value
---------- ----------
A AA
C CC

将数据通过 BCP 导出
BCP [testDev].[dbo].[test_main] out test_main_c.dat -c -T -S "localhost\SQLEXPRESS"
BCP [testDev].[dbo].[test_sub] out test_sub_c.dat -c -T -S "localhost\SQLEXPRESS"

将数据通过 BCP 导入到 另外一个数据库
BCP [testWork].[dbo].[test_main] in test_main_c.dat -c -T -S "localhost\SQLEXPRESS"
BCP [testWork].[dbo].[test_sub] in test_sub_c.dat -c -T -S "localhost\SQLEXPRESS"

在 testWork 数据库中查询

1> select * from test_main
2> go
id value
----------- ----------
1 A
2 C

1> select * from test_sub
2> go
id main_id value
----------- ----------- ----------
1 1 AA
2 3 CC

由于主表的 ID 重新生成了,父子关系不匹配。

BCP 导出格式文件
bcp [testDev].[dbo].[test_main] format nul -f test_main.fmt -c -T -S "localhost\SQLEXPRESS"
bcp [testDev].[dbo].[test_sub] format nul -f test_sub.fmt -c -T -S "localhost\SQLEXPRESS"

使用 OPENROWSET 读取外部数据文件。
SELECT * FROM
OPENROWSET( BULK 'E:\Temp\test_main_c.dat',
FORMATFILE = 'E:\Temp\test_main.fmt') AS a;

id value
------------ ----------
1 A
3 C

-- 首先清空目标表数据
TRUNCATE TABLE test_main;
go
-- 关闭自增ID
SET IDENTITY_INSERT test_main ON
go
-- 插入数据
INSERT INTO test_main(id, value)
SELECT * FROM
OPENROWSET( BULK 'E:\Temp\test_main_c.dat',
FORMATFILE = 'E:\Temp\test_main.fmt') AS a;
go
-- 开启自增.
SET IDENTITY_INSERT test_main OFF
go

-- 首先清空目标表数据
TRUNCATE TABLE test_sub;
go
-- 关闭自增ID
SET IDENTITY_INSERT test_sub ON
go
-- 插入数据
INSERT INTO test_sub(id, main_id, value)
SELECT * FROM
OPENROWSET( BULK 'E:\Temp\test_sub_c.dat',
FORMATFILE = 'E:\Temp\test_sub.fmt') AS a;
go
-- 开启自增.
SET IDENTITY_INSERT test_sub OFF
go

-- 核对导入结果
1> select * from test_main
2> go
id value
----------- ----------
1 A
3 C

(2 行受影响)
1> select * from test_sub
2> go
id main_id value
----------- ----------- ----------
1 1 AA
3 3 CC

(2 行受影响)

-- 查看导入处理完毕后,自增ID的状态.

1> DBCC CHECKIDENT('test_main', NORESEED)
2> go
检查标识信息: 当前标识值 '3',当前列值 '3'。
DBCC 执行完毕。如果 DBCC 输出了错误信息,请与系统管理员联系。

1> DBCC CHECKIDENT('test_sub', NORESEED)
2> go
检查标识信息: 当前标识值 '3',当前列值 '3'。
DBCC 执行完毕。如果 DBCC 输出了错误信息,请与系统管理员联系。

更加省事,简单的处理方式:

可以将包含标识值的数据文件大容量导入到 Microsoft SQL Server 实例中。默认情况下,将忽略导入的数据文件中标识列的值,SQL Server 自动分配唯一值。这些唯一值基于在表创建期间指定的种子和增量值。

如果该数据文件表中的标识符列不包含值,则使用格式化文件来指定导入数据时应跳过表中的标识符列。SQL Server 自动为此列分配唯一值。

若要防止 SQL Server 在将数据行大容量导入到表中时分配标识值,请使用相应的保留标识命令限定符。在您指定保留标识限定符后,SQL Server 将在该数据文件中使用标识值。这些限定符如下:

命令保留标识限定符限定符类型
Bcp-E开关
BULK INSERTKEEPIDENTITY参数
INSERT ...SELECT * FROM OPENROWSET(BULK...)KEEPIDENTITY表提示

BCP 方式
BCP [testWork].[dbo].[test_main] in test_main_c.dat -c -E -T -S "localhost\SQLEXPRESS"
BCP [testWork].[dbo].[test_sub] in test_sub_c.dat -c -E -T -S "localhost\SQLEXPRESS"

BULK INSERT 方式
BULK INSERT test_main
FROM 'E:\Temp\test_main_c.dat'
WITH (
KEEPIDENTITY,
DATAFILETYPE='char'
);

BULK INSERT test_sub
FROM 'E:\Temp\test_sub_c.dat'
WITH (
KEEPIDENTITY,
DATAFILETYPE='char'
);

INSERT ...SELECT * FROM OPENROWSET(BULK...) 方式

INSERT INTO test_main
with (KEEPIDENTITY)
(id, value)
SELECT * FROM
OPENROWSET( BULK 'E:\Temp\test_main_c.dat',
FORMATFILE = 'E:\Temp\test_main.fmt') AS a;

INSERT INTO test_sub
with (KEEPIDENTITY)
(id, main_id, value)
SELECT * FROM
OPENROWSET( BULK 'E:\Temp\test_sub_c.dat',
FORMATFILE = 'E:\Temp\test_sub.fmt') AS a;

回答2:

如果你想要这个自增的数值,就开启这个选项,如果不想要就insert select 的时候把列名都罗列出来,只要不写出标识列,插入时会自动跳过