SQLSERVER:大容量导入数据时保留标识值 (SQL Server)
从MSDN上看到实现大容量导入数据时保留标识值得方法包含三种:
MSDN链接地址为:https://msdn.microsoft.com/zh-cn/library/ms178129.aspx
感觉MSDN上给的列子都没有数据,有些demo不直接,所以这里我要写例子来实现这三种方式。
- bcp
- Bulk Insert From .. With(...)
- Insert Into ... (field1name,field2name...) select field1name,field2name... from openrowset(bulk 'xxx',formatfile='xxx')
下边我们就三种方式展开测试:
整理数据源:
create table dbo.Member(
id bigint identity(1,1) primary key not null,
name nvarchar(64) not null,
nickname nvarchar(64) null,
pwd nvarchar(64) not null,
moneyicon decimal(18,2) null,
gender char(3) not null default(1),
birthday datetime null,
createtime datetime not null default(getdate())
) insert dbo.Member(name,nickname,pwd,moneyicon,gender,birthday,createtime)values('yy3b2007com','cctext','',9000999999999.99,'','1987-01-01',getdate());
insert dbo.Member(name,nickname,pwd,moneyicon,gender,birthday,createtime)values('yy3b2007com1','cctext2','',9000999999999.99,'','1987-01-01',getdate());
insert dbo.Member(name,nickname,pwd,moneyicon,gender,birthday,createtime)values('yy3b2007com11','cctext22','',9000999999999.99,'','1987-01-01',getdate());
insert dbo.Member(name,nickname,pwd,moneyicon,gender,birthday,createtime)values('yy3b2007com111','cctext22','',9000999999999.99,'','1987-01-01',getdate());
- bcp 方式:
要是用bcp操作的话,我们需要在cmd中进行执行,太繁琐,所以我们采用xp_cmdshell方式来执行bcp命令操作。
在使用xp_cmdshell需要开启sqlserver show_advanced options 配置信息:
-- 开启批量导入功能 xp_cmdshell
-- find 'show advanced options' config option from sys.configurations
select * from sys.configurations where name='show advanced options';
go
exec sp_configure 'show_advanced options',1;
reconfigure
go
exec sp_configure 'xp_cmdshell',1;
reconfigure
go
select * from sys.configurations where name='show advanced options';
执行上边命令返回结果信息:

接下来,我们使用xp_cmdshell来执行bcp导出、导入数据操作:
use test_bulkinsert;
-- 导入 dbo.Member中记录到文件 d:/member.txt 中
exec master..xp_cmdshell 'BCP test_bulkinsert.dbo.Member out d:/member.txt -c -S.\network -Usa -Pnew.1234' --begin transaction x1
truncate table dbo.Member;
select * from dbo.Member;
exec master..xp_cmdshell 'bcp test_bulkinsert.dbo.Member in d:/member.txt -c -S.\network -Usa -Pnew.1234'
select * from dbo.Member;
--rollback transaction x1;
执行后返回结果信息:

查看文件member.txt信息:
1 yy3b2007com cctext 123456 9000999999999.99 1 1987-01-01 00:00:00.000 2016-07-27 00:41:48.443
2 yy3b2007com1 cctext2 123456 9000999999999.99 1 1987-01-01 00:00:00.000 2016-07-27 00:41:48.447
3 yy3b2007com11 cctext22 123456 9000999999999.99 1 1987-01-01 00:00:00.000 2016-07-27 00:41:48.447
4 yy3b2007com111 cctext22 123456 9000999999999.99 1 1987-01-01 00:00:00.000 2016-07-27 00:41:48.447
备注:列之间使用'\t'间隔,换行符为‘\r\n’
上边的例子,导出导入的过程包含有id自增列,那么怎么实现导入过程中不包含自增列,让数据库内部自己维护呢?
我们需要使用formatfile---sqlserver格式化文件。具体怎么生成可以参考:https://msdn.microsoft.com/zh-cn/library/ms191516.aspx
格式化文件格式包含两种:一种是非xml格式,一种是xml格式。
A、导入member.txt数据源,并编辑。
执行命令:
use test_bulkinsert;
-- 导入 dbo.Member中记录到文件 d:/member.txt 中
exec master..xp_cmdshell 'BCP test_bulkinsert.dbo.Member out d:/member.txt -c -T -S.\network -Usa -Pnew.1234'
生成文件member.txt.
1 yy3b2007com cctext 123456 9000999999999.99 1 1987-01-01 00:00:00.000 2016-07-27 01:39:58.180
2 yy3b2007com1 cctext2 123456 9000999999999.99 1 1987-01-01 00:00:00.000 2016-07-27 01:39:58.180
3 yy3b2007com11 cctext22 123456 9000999999999.99 1 1987-01-01 00:00:00.000 2016-07-27 01:39:58.180
4 yy3b2007com111 cctext22 123456 9000999999999.99 1 1987-01-01 00:00:00.000 2016-07-27 01:39:58.180
编辑为:
yy3b2007com cctext 123456 9000999999999.99 1 1987-01-01 00:00:00.000 2016-07-27 01:39:58.180
yy3b2007com1 cctext2 123456 9000999999999.99 1 1987-01-01 00:00:00.000 2016-07-27 01:39:58.180
yy3b2007com11 cctext22 123456 9000999999999.99 1 1987-01-01 00:00:00.000 2016-07-27 01:39:58.180
yy3b2007com111 cctext22 123456 9000999999999.99 1 1987-01-01 00:00:00.000 2016-07-27 01:39:58.180
B、生成非xml格式化文件:
执行命令:
-- 生成文件member-f-c-x.xml文件,编辑为member-f-c-x-without-id.Xml
exec master..xp_cmdshell 'bcp test_bulkinsert.dbo.Member format nul -S.\network -Usa -Pnew.1234 -c -f d:/member-f-c.Xml -T'
修改非xml格式化文件member-f-c.Xml
原始文件信息为:
10.0
8
1 SQLCHAR 0 21 "\t" 1 id ""
2 SQLCHAR 0 128 "\t" 2 name Chinese_PRC_CI_AS
3 SQLCHAR 0 128 "\t" 3 nickname Chinese_PRC_CI_AS
4 SQLCHAR 0 128 "\t" 4 pwd Chinese_PRC_CI_AS
5 SQLCHAR 0 41 "\t" 5 moneyicon ""
6 SQLCHAR 0 3 "\t" 6 gender Chinese_PRC_CI_AS
7 SQLCHAR 0 24 "\t" 7 birthday ""
8 SQLCHAR 0 24 "\r\n" 8 createtime ""
修改为:
10.0
7
1 SQLCHAR 0 128 "\t" 2 name Chinese_PRC_CI_AS
2 SQLCHAR 0 128 "\t" 3 nickname Chinese_PRC_CI_AS
3 SQLCHAR 0 128 "\t" 4 pwd Chinese_PRC_CI_AS
4 SQLCHAR 0 41 "\t" 5 moneyicon ""
5 SQLCHAR 0 3 "\t" 6 gender Chinese_PRC_CI_AS
6 SQLCHAR 0 24 "\t" 7 birthday ""
7 SQLCHAR 0 24 "\r\n" 8 createtime ""
C、执行导入保留标识值:
truncate table dbo.Member;
select * from dbo.Member;
exec master..xp_cmdshell 'bcp test_bulkinsert.dbo.Member in d:/member.txt -f d:/member-f-c.xml -E -T -S.\network -Usa -Pnew.1234'
select * from dbo.Member;
- Bulk Insert From .. With(...) 方式:
BULK INSERT微软官网上看到是SQLSERVER2008才开启的功能,但是仔细查看发现SQLSERVER2005也支持该操作。
DSDN语法参考英文地址:https://msdn.microsoft.com/en-us/library/ms188365.aspx
DSDN语法参考中文地址:https://msdn.microsoft.com/zh-cn/library/ms188365.aspx
A、生成xml格式化文件:
exec master..xp_cmdshell 'bcp test_bulkinsert.dbo.Member format nul -S.\network -Usa -Pnew.1234 -c -t\t -x -f d:/myTestFormatFiles.Xml -T'
myTestFormatFiles.Xml信息为:
<?xml version="1.0"?>
<BCPFORMAT xmlns="http://schemas.microsoft.com/sqlserver/2004/bulkload/format" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<RECORD>
<FIELD ID="1" xsi:type="CharTerm" TERMINATOR="\t" MAX_LENGTH="21"/>
<FIELD ID="2" xsi:type="CharTerm" TERMINATOR="\t" MAX_LENGTH="128" COLLATION="Chinese_PRC_CI_AS"/>
<FIELD ID="3" xsi:type="CharTerm" TERMINATOR="\t" MAX_LENGTH="128" COLLATION="Chinese_PRC_CI_AS"/>
<FIELD ID="4" xsi:type="CharTerm" TERMINATOR="\t" MAX_LENGTH="128" COLLATION="Chinese_PRC_CI_AS"/>
<FIELD ID="5" xsi:type="CharTerm" TERMINATOR="\t" MAX_LENGTH="41"/>
<FIELD ID="6" xsi:type="CharTerm" TERMINATOR="\t" MAX_LENGTH="3" COLLATION="Chinese_PRC_CI_AS"/>
<FIELD ID="7" xsi:type="CharTerm" TERMINATOR="\t" MAX_LENGTH="24"/>
<FIELD ID="8" xsi:type="CharTerm" TERMINATOR="\r\n" MAX_LENGTH="24"/>
</RECORD>
<ROW>
<COLUMN SOURCE="1" NAME="id" xsi:type="SQLBIGINT"/>
<COLUMN SOURCE="2" NAME="name" xsi:type="SQLNVARCHAR"/>
<COLUMN SOURCE="3" NAME="nickname" xsi:type="SQLNVARCHAR"/>
<COLUMN SOURCE="4" NAME="pwd" xsi:type="SQLNVARCHAR"/>
<COLUMN SOURCE="5" NAME="moneyicon" xsi:type="SQLDECIMAL" PRECISION="18" SCALE="2"/>
<COLUMN SOURCE="6" NAME="gender" xsi:type="SQLCHAR"/>
<COLUMN SOURCE="7" NAME="birthday" xsi:type="SQLDATETIME"/>
<COLUMN SOURCE="8" NAME="createtime" xsi:type="SQLDATETIME"/>
</ROW>
</BCPFORMAT>
修改,并把修改后的信息保存在myTestFormatFiles_without_id.Xml。
<?xml version="1.0"?>
<BCPFORMAT xmlns="http://schemas.microsoft.com/sqlserver/2004/bulkload/format" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<RECORD>
<FIELD ID="1" xsi:type="CharTerm" TERMINATOR="\t" MAX_LENGTH="128" COLLATION="Chinese_PRC_CI_AS"/>
<FIELD ID="2" xsi:type="CharTerm" TERMINATOR="\t" MAX_LENGTH="128" COLLATION="Chinese_PRC_CI_AS"/>
<FIELD ID="3" xsi:type="CharTerm" TERMINATOR="\t" MAX_LENGTH="128" COLLATION="Chinese_PRC_CI_AS"/>
<FIELD ID="4" xsi:type="CharTerm" TERMINATOR="\t" MAX_LENGTH="41"/>
<FIELD ID="5" xsi:type="CharTerm" TERMINATOR="\t" MAX_LENGTH="3" COLLATION="Chinese_PRC_CI_AS"/>
<FIELD ID="6" xsi:type="CharTerm" TERMINATOR="\t" MAX_LENGTH="24"/>
<FIELD ID="7" xsi:type="CharTerm" TERMINATOR="\r\n" MAX_LENGTH="24"/>
</RECORD>
<ROW>
<COLUMN SOURCE="1" NAME="name" xsi:type="SQLNVARCHAR"/>
<COLUMN SOURCE="2" NAME="nickname" xsi:type="SQLNVARCHAR"/>
<COLUMN SOURCE="3" NAME="pwd" xsi:type="SQLNVARCHAR"/>
<COLUMN SOURCE="4" NAME="moneyicon" xsi:type="SQLDECIMAL" PRECISION="18" SCALE="2"/>
<COLUMN SOURCE="5" NAME="gender" xsi:type="SQLCHAR"/>
<COLUMN SOURCE="6" NAME="birthday" xsi:type="SQLDATETIME"/>
<COLUMN SOURCE="7" NAME="createtime" xsi:type="SQLDATETIME"/>
</ROW>
</BCPFORMAT>
修改member.txt,并把修改后的信息保存在member_without_id.txt
yy3b2007com cctext 123456 9000999999999.99 1 1987-01-01 00:00:00.000 2016-07-27 00:41:48.443
yy3b2007com1 cctext2 123456 9000999999999.99 1 1987-01-01 00:00:00.000 2016-07-27 00:41:48.447
yy3b2007com11 cctext22 123456 9000999999999.99 1 1987-01-01 00:00:00.000 2016-07-27 00:41:48.447
yy3b2007com111 cctext22 123456 9000999999999.99 1 1987-01-01 00:00:00.000 2016-07-27 00:41:48.447
B、执行插入命令:
use test_bulkinsert
truncate table dbo.Member; bulk insert dbo.Member
from 'd://member_without_id.txt'
with(
formatfile='d://myTestFormatFiles_without_id.Xml'
)
select * from dbo.Member;
- Insert Into ... (field1name,field2name...) select field1name,field2name... from openrowset(bulk 'xxx',formatfile='xxx') 方式:
可以使用Bulk Insert方式格式化文件,和数据文件来测试:
use test_bulkinsert
truncate table dbo.Member; insert into dbo.Member(name,nickname,pwd,moneyicon,gender,birthday,createtime)
select * from
openrowset(bulk 'd://member_without_id.txt',formatfile='d://myTestFormatFiles_without_id.Xml') as t select * from dbo.Member;
以上就是SQLServer三种方式实现大容量导入数据时保留标识值的完整示例。
- 完整代码测试:
USE [test_bulkinsert]
GO
/****** Object: Table [dbo].[Member] Script Date: 07/27/2016 02:07:26 ******/
IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[DF__Member__gender__0EA330E9]') AND type = 'D')
BEGIN
ALTER TABLE [dbo].[Member] DROP CONSTRAINT [DF__Member__gender__0EA330E9]
END
GO
IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[DF__Member__createti__0F975522]') AND type = 'D')
BEGIN
ALTER TABLE [dbo].[Member] DROP CONSTRAINT [DF__Member__createti__0F975522]
END
GO
IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[Member]') AND type in (N'U'))
DROP TABLE [dbo].[Member]
GO
/****** Object: Table [dbo].[Member] Script Date: 07/27/2016 02:07:26 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[Member]') AND type in (N'U'))
BEGIN
CREATE TABLE [dbo].[Member](
[id] [bigint] IDENTITY(1,1) NOT NULL,
[name] [nvarchar](64) NOT NULL,
[nickname] [nvarchar](64) NULL,
[pwd] [nvarchar](64) NOT NULL,
[moneyicon] [decimal](18, 2) NULL,
[gender] [char](3) NOT NULL DEFAULT ((1)),
[birthday] [datetime] NULL,
[createtime] [datetime] NOT NULL DEFAULT (getdate()),
PRIMARY KEY CLUSTERED
(
[id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
END
GO
SET ANSI_PADDING OFF
GO insert dbo.Member(name,nickname,pwd,moneyicon,gender,birthday,createtime)values('yy3b2007com','cctext','',9000999999999.99,'','1987-01-01',getdate());
insert dbo.Member(name,nickname,pwd,moneyicon,gender,birthday,createtime)values('yy3b2007com1','cctext2','',9000999999999.99,'','1987-01-01',getdate());
insert dbo.Member(name,nickname,pwd,moneyicon,gender,birthday,createtime)values('yy3b2007com11','cctext22','',9000999999999.99,'','1987-01-01',getdate());
insert dbo.Member(name,nickname,pwd,moneyicon,gender,birthday,createtime)values('yy3b2007com111','cctext22','',9000999999999.99,'','1987-01-01',getdate()); -- 开启批量导入功能 xp_cmdshell
-- find 'show advanced options' config option from sys.configurations
select * from sys.configurations where name='show advanced options';
go
exec sp_configure 'show_advanced options',1;
reconfigure
go
exec sp_configure 'xp_cmdshell',1;
reconfigure
go
select * from sys.configurations where name='show advanced options'; use test_bulkinsert;
-- 导入 dbo.Member中记录到文件 d:/member.txt 中
exec master..xp_cmdshell 'BCP test_bulkinsert.dbo.Member out d:/member.txt -c -T -S.\network -Usa -Pnew.1234'
-- 生成文件member-f-c-x.xml文件,编辑为member-f-c-x-without-id.Xml
exec master..xp_cmdshell 'bcp test_bulkinsert.dbo.Member format nul -S.\network -Usa -Pnew.1234 -c -f d:/member-f-c.Xml -T'
--begin transaction x1
truncate table dbo.Member;
select * from dbo.Member;
exec master..xp_cmdshell 'bcp test_bulkinsert.dbo.Member in d:/member.txt -f d:/member-f-c.xml -E -T -S.\network -Usa -Pnew.1234'
select * from dbo.Member;
--rollback transaction x1; exec master..xp_cmdshell 'bcp test_bulkinsert.dbo.Member format nul -S.\network -Usa -Pnew.1234 -c -t\t -x -f d:/myTestFormatFiles.Xml -T' use test_bulkinsert
truncate table dbo.Member; bulk insert dbo.Member
from 'd://member_without_id.txt'
with(
formatfile='d://myTestFormatFiles_without_id.Xml'
)
select * from dbo.Member; use test_bulkinsert
truncate table dbo.Member; insert into dbo.Member(name,nickname,pwd,moneyicon,gender,birthday,createtime)
select * from
openrowset(bulk 'd://member_without_id.txt',formatfile='d://myTestFormatFiles_without_id.Xml') as t select * from dbo.Member;
- 具体参考资料:
MSDN BULK INSERT (Transact-SQL):https://msdn.microsoft.com/zh-cn/zh-ch/library/ms188365.aspx
MSDN 大容量导入数据时保留标识值 (SQL Server):https://msdn.microsoft.com/zh-cn/library/ms186335.aspx
MSDN 创建格式化文件 (SQL Server):https://msdn.microsoft.com/zh-cn/library/ms191516.aspx
MSDN 使用格式化文件大容量导入数据 (SQL Server):https://msdn.microsoft.com/zh-cn/library/ms178129.aspx
SQLSERVER:大容量导入数据时保留标识值 (SQL Server)的更多相关文章
- 导入数据时出现“SqlDateTime 溢出
错误出现:导入数据时出现“SqlDateTime 溢出.必须介于 1/1/1753 12:00:00 AM 和 12/31/9999 11:59:59 PM之间.” 出现这种问题多半是因为你插入或者更 ...
- SQL Server导入数据时“启用标示插入”详解
在SQL Server中导入数据时,会有一个"启用标示插入"的选项,突然间懵逼了,这到底啥意思?我选与不选这个选项,结果好像没区别!不科学啊这,"存在即合理", ...
- 解决SQLSERVER在还原数据时出现的“FILESTREAM功能被禁用”问题
解决SQLSERVER在还原数据时出现的“FILESTREAM功能被禁用”问题 今天由于测试需要,在网上下载了Adventureworks2008实例数据库的BAK文件,进行还原时出现了这样的错误“F ...
- [MySQL]load data local infile向MySQL数据库中导入数据时,无法导入和字段不分离问题。
利用load data将文件中的数据导入数据库表中的时候,遇到了两个问题. 首先是load data命令无法执行的问题: 命令行下输入load data local infile "path ...
- 转 SSIS处理导入数据时, 存在的更新, 不存在的插入
SSIS处理导入数据时, 存在的更新, 不存在的插入 分类: DTS/SSIS2006-09-10 12:43 18185人阅读 评论(22) 收藏 举报 ssissql servermicrosof ...
- MSSQL导入数据时,出现“无法截断表 因为表正由Foreign key引用”错误
* 错误 0xc002f210: 准备 SQL 任务: 执行查询“TRUNCATE TABLE [dsc100552_db].[dbo].[ALV_SalesBigClass] ”失败,错误如下:“无 ...
- 使用Sqoop从mysql向hdfs或者hive导入数据时出现的一些错误
1.原表没有设置主键,出现错误提示: ERROR tool.ImportTool: Error during import: No primary key could be found for tab ...
- 从Excel中导入数据时,提示“未在本地计算机上注册“Microsoft.ACE.OLEDB.12.0”提供程序”的解决办法
注意,64位系统,用64位的补丁文件; https://www.cnblogs.com/A2008A/articles/2438962.html 操作系统:使用的是64位的Windows Server ...
- DB2导入数据时乱码问题
1.由于导入import导入数据时乱码,一直找不到解决办法,于是就用load导入 LOAD后,发现某些表检查挂起( 原因码为 "1",所以不允许操作 SQLSTATE=57016 ...
随机推荐
- linux C gcc -lm
使用math.h中声明的库函数还有一点特殊之处,gcc命令行必须加-lm选项,因为数学函数位于libm.so库文件中(这些库文件通常位于/lib目录下),-lm选项告诉编译器,我们程序中用到的数学函数 ...
- [收藏]ASP.NET MVC管道详述
ASP.NET MVC从诞生到现在已经好几个年头了,这个框架提供一种全新的开发模式,更符合web开发本质.你可以很好的使用以及个性化和扩展这个框架,但这需要你对它有足够的了解.这篇文章主要从整体角度总 ...
- 超简单的处理JSON格式和JSON数组格式的String
现在网站上有不少处理JSON格式的工具类,但是我找了一天,发现大都是需要编写相应对象类来进行处理,比较麻烦,比如:Gson,json-lib.Gson,json-lib这些处理那些接口之类的参数名字和 ...
- MVC3下的layout页面
1.Layout页基础:如果你有使用MasterPage的经验,你将会记得如下的几个东西 A:<%@ Master %> B:<%@ Page %> C:<asp:Con ...
- addChildViewController相关api深入剖析
注:本文根据个人的实践和理解写成,若有不当之处欢迎斧正和探讨! addChildViewController是一个从iOS5开始支持的api接口,相关的一系列的接口是用来处理viewcontrolle ...
- XCode中的单元测试:编写测试类和方法(内容意译自苹果官方文档)
当你在工程中通过测试导航栏添加了一个测试target之后, xcode会在测试导航栏中显示该target所属的测试类和方法. 这一章演示了怎么创建测试类,以及如何编写测试方法. 测试targets, ...
- WPF绑定方式
绑定到其它元素 <Grid> <StackPanel> <TextBox x:Name="textbox1" /> ...
- MongoDB的find用法
0.查询符合条件数据的总条数 如:db.list名.find({条件}).count(); 1.返回指定的键值:db.list.find({条件},{name:"任意值",age: ...
- map和json之间的转换
Action中在session中存放了一个map<String,Object>,跳转到a.jsp,a.jsp通过form提交到BAction,BAction可从session中获得map值 ...
- Oracle数据导入导出imp/exp
功能:Oracle数据导入导出imp/exp就相当与oracle数据还原与备份. 大多情况都可以用Oracle数据导入导出完成数据的备份和还原(不会造成数据的丢失). Oracle有个好处,虽然你的电 ...