SQL Server Bulk Insert 批量数据导入

时间:2021-05-24 00:41:57

SQL Server的Bulk Insert语句可以将本地或远程的数据文件批量导入到数据库中,速度非常的快。远程文件必须共享才行,文件路径须使用通用约定(UNC)名称,即"\\服务器名或IP\共享名\路径\文件名"的形式。

 

* 1. 由于Bulk Insert通常配合格式化文件批量导入数据更方便,所以这里先介绍bcp工具导出格式化文件的方法。

bcp是SQL Server提供的命令行实用工具提供了数据的导出、导入、格式文件导出等功能,导出格式化文件的语法如下:

Sql代码  SQL Server Bulk Insert 批量数据导入
  1. bcp 数据库名.用户名.表名 format nul -- 这里的nul必须存在,用于不是导出和导入数据的情况下  
  2. -f 输出的格式化文件名 [-x] -c  -- -x参数指定输出的格式文件为xml格式(默认非xml格式); -c参数指定数据存储方式为字符,并默认指定'\t'作为字段间隔符;'\n'作为行间隔符  
  3. [-t 字段间隔符] [-r 行间隔符号]  -- -t与-r参数可选,用于覆盖-c指定的默认间隔符  
  4. -T -- 指定数据库连接可信,即使用Windows身份登录  

* 2. Bulk Insert

 根据格式文件导入数据文件,语法格式如下:

Sql代码  SQL Server Bulk Insert 批量数据导入
  1. Bulk insert 数据库名.用户名.表名  
  2. from '数据文件路径'  
  3. with  
  4. (  
  5. formatfile = '格式文件路径',  
  6. FirstRow = 2    --指定数据文件中开始的行数,默认是1  
  7. )  

 

* 3. OPENRORWSET(BULK)函数

有时,使用OPENROWSET(BULK)函数可以更灵活地选取想要的字段插入到原表或者其他表中,其语法格式为:

Sql代码  SQL Server Bulk Insert 批量数据导入
  1. INSERT INTO to_table_name SELECT filed_name_list  
  2. FROM OPENROWSET(BULK N'path_to_data_file', FORMATFILE=N'path_to_format_file'AS new_table_name  
  

  当然,该函数也可以这么使用:

Sql代码  SQL Server Bulk Insert 批量数据导入
  1. SELECT field_name_list INTO temp_table_name  
  2. FROM OPENROWSET(BULK N'path_to_data_file', FORMATFILE=N'path_to_format_file'AS new_table_name  
 

 

下面举一个完整的例子:

 

1)创建数据库、表并填充测试数据,脚本如下:

Sql代码  SQL Server Bulk Insert 批量数据导入
  1. -- 创建数据库  
  2. CREATE DATABASE [db_mgr]  
  3. GO  
  4. --创建测试表  
  5. USE db_mgr  
  6. CREATE TABLE dbo.T_Student(  
  7.     F_ID [int] IDENTITY(1,1) NOT NULL,  
  8.     F_Code varchar(10) ,  
  9.     F_Name varchar(100) ,  
  10.     F_Memo nvarchar(500) ,  
  11.     F_Memo2 ntext ,  
  12.     PRIMARY KEY  (F_ID)  
  13. )   
  14. GO  
  15.   
  16. --填充测试数据  
  17. Insert Into T_Student(F_Code, F_Name, F_Memo, F_Memo2) select  
  18. 'code001''name001''memo001''备注001' union all select  
  19. 'code002''name002''memo002''备注002' union all select  
  20. 'code003''name003''memo003''备注003' union all select  
  21. 'code004''name004''memo004''备注004' union all select  
  22. 'code005''name005''memo005''备注005' union all select  
  23. 'code006''name006''memo006''备注006'  

  2)我们可以使用SQL Server的master..xp_cmdshell存储过程将CMD的命令传给系统,这样就可以直接在SQL Server的查询处理器中直接输入bcp的命令,而不用切换到命令模式下执行。SQL Server 出于安全目的默认将该存储过程禁用了,开启方法如下:

Sql代码  SQL Server Bulk Insert 批量数据导入
  1. --开启xp_cmdshell存储过程(开启后有安全隐患)  
  2. EXEC sp_configure 'show advanced options', 1;  
  3. RECONFIGURE;EXEC sp_configure 'xp_cmdshell', 1;  
  4. EXEC sp_configure 'show advanced options', 0;  
  5. RECONFIGURE;  

 

3)使用bcp导出格式文件:

Sql代码  SQL Server Bulk Insert 批量数据导入
  1. EXEC master..xp_cmdshell 'BCP db_mgr.dbo.T_Student format nul -f C:/student_fmt.xml -x -c -T'  

 

4)使用bcp导出数据文件:

Sql代码  SQL Server Bulk Insert 批量数据导入
  1. EXEC master..xp_cmdshell 'BCP db_mgr.dbo.T_Student out C:/student.data -f C:/student_fmt.xml -T'  
  2. truncate table db_mgr.dbo.T_Student -- 将表中数据清空  

  注意:在实际使用过程中,数据文件可以由程序生成,如日志记录等!

 

5)使用Bulk Insert语句批量导入数据文件:

Sql代码  SQL Server Bulk Insert 批量数据导入
  1. BULK INSERT db_mgr.dbo.T_Student  
  2. FROM 'C:/student.data'  
  3. WITH  
  4. (  
  5.     FORMATFILE = 'C:/student_fmt.xml'  
  6. )  

 

6)使用OPENROWSET(BULK)的例子:

Sql代码  SQL Server Bulk Insert 批量数据导入
  1. INSERT INTO db_mgr.dbo.T_Student(F_Code, F_Name) SELECT F_Code, F_Name  
  2. FROM OPENROWSET(BULK N'C:/student_c.data', FORMATFILE=N'C:/student_fmt_c.xml'AS new_table_name -- T_Student表必须已存在  
  3.   
  4. SELECT F_Code, F_Name INTO db_mgr.dbo.tt  
  5. FROM OPENROWSET(BULK N'C:/student_c.data', FORMATFILE=N'C:/student_fmt_c.xml'AS new_table_name -- tt表可以不存在  

 

 

参考:

使用 BULK INSERT 或 OPENROWSET(BULK...) 导入大容量数据(尤其是关于安全的那部分,导入远程文件时应特别注意):

http://msdn.microsoft.com/zh-cn/library/ms175915.aspx

创建格式化文件:

http://msdn.microsoft.com/zh-cn/library/ms191516.aspx

OPENROWSET (Transact-SQL):

http://msdn.microsoft.com/zh-cn/library/ms190312.aspx

BULK INSERT (Transact-SQL):

http://msdn.microsoft.com/zh-cn/library/ms188365.aspx

bcp 实用工具:

http://msdn.microsoft.com/zh-cn/library/ms162802.aspx