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 ...
随机推荐
- 鼠标选择文字事件js代码,增加层问题
在页面中增加一个js代码,当用户用鼠标选择文字(鼠标拖动涂蓝文字)时,会出现一个层,提示与这个选择文字有个的信息<script type="text/javascript"& ...
- [SHELL实例] (转)最牛B的 Linux Shell 命令 (一)
本文编译自commandlinefu.com ( 应该是 Catonmat ) 的系列文章 Top Ten One-Liners from CommandLineFu Explained .作为一个由 ...
- 利用EXCEL表实现网页数据采集到MYSQL数据库
先复制页面表格数据到EXCEL中,比如 2012-1-4 52.7 52.7 49 48.83 190007 9506968 2012-1-5 48.86 49.79 45.72 45.6 62325 ...
- mysql的事务和select...for update
一.mysql的事务mysql的事务有两种方式:1.SET AUTOCOMMIT=0;也就是关闭了自动提交,那么任何commit或rollback语句都可以触发事务提交;如果SET AUTOCOMMI ...
- Apache Kafka源码分析 - KafkaApis
kafka apis反映出kafka broker server可以提供哪些服务,broker server主要和producer,consumer,controller有交互,搞清这些api就清楚了 ...
- ifarm 子 父页面方法如何互调
1.iframe子页面调用父页面js函数 子页面调用父页面函数只需要写上window.praent就可以了.比如调用a()函数,就写成: 代码如下: window.parent.a(); 子页面取父页 ...
- html之内联元素与块状元素;
html之内联元素与块状元素 一.html之内联元素与块状元素 1.块状元素一般比较霸道,它排斥与其他元素位于同一行内.比如div,并且width与height对它起作用. 2.内联元素只能容纳文本或 ...
- 面向对象之struct
struct PointStruct { int pointx = 1; int pointy = 2; public PointStruct(int x, int y) { this.pointx ...
- BLE-NRF51822教程-RSSI获取
当手机和设备连接上后,设备端可以通过获取RSSI,在一定程度上判断手机离设备的相对距离的远近. 获取函数很简单直接调用sd_ble_gap_rssi_get 接口函数就行了,传入连接句柄和buff就能 ...
- 计算A+B及其结果的标准形式输出
题目: 代码链接 解题思路: 首先,读懂题目,题目要求我们计算两个整型数a,b之和,这是简单的加法计算,与平常的题目一般无二.但是此题的不同在于要求我们输出的数必须是标准形式,题目也对标准形式做了相应 ...