You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SQL Server批量插入带双引号字段CSV的格式文件正确格式

解决BULK INSERT导入带双引号CSV时残留引号的问题

我之前也碰到过这个一模一样的头疼问题!用bcp生成格式文件后改来改去,结果总有字段带着双引号残留,后来才搞明白:SQL Server不会自动识别CSV里的引号包裹,必须在格式文件里明确告诉它要处理引号。

问题根源

你的CSV格式是每个字段都用双引号包裹(包括空值的""),比如示例行:

"SONC","Sonic Corp.","981","amc","0.22","0.24","+0.02","+9.09%","5.15%",""

默认bcp生成的格式文件只会处理分隔符(比如逗号),不会理会引号——所以如果只是把终止符改成",",SQL Server会把引号当成字段内容的一部分,导致导入后残留引号。

解决方案:用XML格式文件处理引号

XML格式文件比传统的非XML格式更灵活,能直接指定QUOTE属性让SQL Server自动去掉字段前后的双引号。下面是针对你的CSV结构的完整示例:

1. 创建XML格式文件(比如stock_format.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>
  <!-- 前9个字段的终止符是",",每个字段都用双引号包裹 -->
  <FIELD ID="1" xsi:type="CharTerm" TERMINATOR='","' QUOTE='"'/>
  <FIELD ID="2" xsi:type="CharTerm" TERMINATOR='","' QUOTE='"'/>
  <FIELD ID="3" xsi:type="CharTerm" TERMINATOR='","' QUOTE='"'/>
  <FIELD ID="4" xsi:type="CharTerm" TERMINATOR='","' QUOTE='"'/>
  <FIELD ID="5" xsi:type="CharTerm" TERMINATOR='","' QUOTE='"'/>
  <FIELD ID="6" xsi:type="CharTerm" TERMINATOR='","' QUOTE='"'/>
  <FIELD ID="7" xsi:type="CharTerm" TERMINATOR='","' QUOTE='"'/>
  <FIELD ID="8" xsi:type="CharTerm" TERMINATOR='","' QUOTE='"'/>
  <FIELD ID="9" xsi:type="CharTerm" TERMINATOR='","' QUOTE='"'/>
  <!-- 最后一个字段的终止符是" + 行结束符(\r\n) -->
  <FIELD ID="10" xsi:type="CharTerm" TERMINATOR='"\r\n' QUOTE='"'/>
 </RECORD>
 <ROW>
  <!-- 这里要对应你的目标表字段名和SQL类型 -->
  <COLUMN SOURCE="1" NAME="Symbol" xsi:type="SQLVARYCHAR"/>
  <COLUMN SOURCE="2" NAME="CompanyName" xsi:type="SQLVARYCHAR"/>
  <COLUMN SOURCE="3" NAME="SomeNum" xsi:type="SQLINT"/>
  <COLUMN SOURCE="4" NAME="Exchange" xsi:type="SQLVARYCHAR"/>
  <COLUMN SOURCE="5" NAME="Price1" xsi:type="SQLDECIMAL" PRECISION="5" SCALE="2"/>
  <COLUMN SOURCE="6" NAME="Price2" xsi:type="SQLDECIMAL" PRECISION="5" SCALE="2"/>
  <COLUMN SOURCE="7" NAME="ChangeVal" xsi:type="SQLVARYCHAR"/>
  <COLUMN SOURCE="8" NAME="ChangePct" xsi:type="SQLVARYCHAR"/>
  <COLUMN SOURCE="9" NAME="PctOfSomething" xsi:type="SQLVARYCHAR"/>
  <COLUMN SOURCE="10" NAME="EmptyField" xsi:type="SQLVARYCHAR"/>
 </ROW>
</BCPFORMAT>

2. 执行BULK INSERT命令

假设你的目标表叫StockData,CSV路径是C:\Data\stocks.csv,格式文件路径是C:\Data\stock_format.xml,执行以下SQL:

BULK INSERT StockData
FROM 'C:\Data\stocks.csv'
WITH (
    FORMATFILE = 'C:\Data\stock_format.xml',
    FIRSTROW = 1, -- 如果CSV有表头行,改成2跳过表头
    ROWTERMINATOR = '\r\n' -- 和格式文件里的行终止符保持一致
);

关键说明

  • QUOTE='"'属性:这是核心!告诉SQL Server每个字段被双引号包裹,导入时会自动去掉前后的引号,包括空值的""会被处理成空字符串(如果目标字段允许NULL,会转成NULL)。
  • 字段终止符:前9个字段的终止符是","(对应CSV里字段之间的","),最后一个字段的终止符是"\r\n"(对应行尾的"加上换行)。
  • 类型转换:如果目标字段是数值类型(比如INT、DECIMAL),在<COLUMN>节点里指定对应的SQL类型(比如SQLINT、SQLDECIMAL),SQL Server会自动完成类型转换,不需要手动处理引号和数值格式。

为什么之前的格式文件没用?

你用bcp生成的默认格式文件没有QUOTE属性,就算修改了终止符,SQL Server也不知道要去掉引号——它只会把引号当成字段内容的一部分,所以才会残留。XML格式文件的QUOTE属性是解决这个问题的关键。

内容的提问来源于stack exchange,提问作者Tony_Henrich

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 03:37:29