【问题标题】:Problems using BULK INSERTwith format file and double quotes in CSV在 CSV 中使用带有格式文件和双引号的 BULK INSERT 时出现问题
【发布时间】:2017-06-01 10:02:47
【问题描述】:

我正在使用 SQL Server 2014 和引用 .csv 文件和格式文件的 BULK INSERT 命令。在所有字段(包括列标题)之前,我已经成功完成了此操作,但现在数据格式略有变化,第一列标题和数据未包含在双引号中,并且在创建格式文件时出现问题。

示例数据...

Number of Employees;"Employee - First Name (Key)";"Employee - Last Name   (Key)";"Employee - E-Mail Address (Key)"
1;"Joe";"Bloggs";"joebloggs@msn.com"

注意,分号是字段分隔符,第一列标题和数据没有引号,后面的所有标题和数据都是一致的

fmt 格式文件示例...

12.0
5
1       SQLCHAR             0       0      "\""    0     ""                                                          ""
2       SQLCHAR             2       50      ";"   1  "Number of   Employees"                                        Latin1_General_CI_AS
3       SQLNCHAR            2       510     "\";\""   2    "Employee First Name"                                        Latin1_General_CI_AS
4       SQLNCHAR            2       510     "\";\""   3     "Employee Last Name"                                        Latin1_General_CI_AS
5       SQLNCHAR            2       510     "\"\r\n"  4     "E-Mail Address"                                             Latin1_General_CI_AS

我已经为第一列尝试了各种分隔符排列,删除了虚拟列,在第一列之前和之后(以上是最新的),但我仍然收到相同的错误消息...

无法批量加载,因为文件“\Mypath\import_staff_dq.fmt”不完整或无法读取。操作系统错误代码(空)。

文件总是关闭的。

为简单起见,我已将 dest 表中的所有字段设置为 VARCHAR

【问题讨论】:

  • BULK INSERT 不支持复杂的 CSV 文件,即带有换行符或带引号的字符串的文件。这将在 SQL Server 2017 中提供。为此使用 SSIS。您可以使用 SSMS 中的Import Data 向导导入 CSV 数据保存 SSIS 包以供重复使用。最常见的场景是使用 SSIS 进行导入和转换,而不是直接 bcp 或 BULK INSERT
  • 它应该与我已成功使用的伴随格式文件 ('fmt') 一起工作,当所有字段都用双引号引起来时,但在第一列没有包装的情况下,它不能像上面描述的那样工作引号。

标签: sql-server csv bulkinsert


【解决方案1】:

我发现 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=';"' MAX_LENGTH="10"/>  
  <FIELD ID="2" xsi:type="CharTerm" TERMINATOR='";"' MAX_LENGTH="4000" COLLATION="SQL_Latin1_General_CP1_CI_AS"/>  
  <FIELD ID="3" xsi:type="CharTerm" TERMINATOR='";"' MAX_LENGTH="4000" COLLATION="SQL_Latin1_General_CP1_CI_AS"/>  
  <FIELD ID="4" xsi:type="CharTerm" TERMINATOR='"\r\n' MAX_LENGTH="4000" COLLATION="SQL_Latin1_General_CP1_CI_AS"/>  
 </RECORD>  
 <ROW>  
  <COLUMN SOURCE="1" NAME="NumberOfEmployees" xsi:type="SQLNVARCHAR"/>  
  <COLUMN SOURCE="2" NAME="EmployeeFirstName" xsi:type="SQLNVARCHAR"/>  
  <COLUMN SOURCE="3" NAME="EmployeeLastName" xsi:type="SQLNVARCHAR"/>  
  <COLUMN SOURCE="4" NAME="EmailAddress" xsi:type="SQLNVARCHAR"/>  
 </ROW>  
</BCPFORMAT>  

使用openrowset(bulk ...)

select *
from openrowset (
    bulk 'c:\tmp.csv'
  , formatfile='c:\tmp.xml'
  , firstrow=2
  ) as t

返回:

+-------------------+-------------------+------------------+-------------------+
| NumberOfEmployees | EmployeeFirstName | EmployeeLastName |   EmailAddress    |
+-------------------+-------------------+------------------+-------------------+
|                 1 | Joe               | Bloggs           | joebloggs@msn.com |
+-------------------+-------------------+------------------+-------------------+

参考:


我也可以使用非 xml 格式的文件获得相同的结果,如下所示:

12.0
4
1    SQLCHAR    0    0    ";\""       1    NumberOfEmployees   Latin1_General_CI_AS
2    SQLCHAR    0    0     "\";\""    2    EmployeeFirstName   Latin1_General_CI_AS
3    SQLCHAR    0    0     "\";\""    3    EmployeeLastName    Latin1_General_CI_AS
4    SQLCHAR    0    0     "\"\r\n"   4    EmailAddress        Latin1_General_CI_AS

【讨论】:

  • @KevinM 乐于助人!
猜你喜欢
  • 2012-07-15
  • 1970-01-01
  • 1970-01-01
  • 2021-10-28
  • 2014-04-22
  • 2015-01-05
  • 1970-01-01
  • 2016-03-04
  • 2013-01-11
相关资源
最近更新 更多