导入时跳过第一个数据行

时间:2013-09-11 20:13:58

标签: sql-server csv import

我正在使用XML格式文件导入CSV文件,并且第一个数据行被跳过。我无法弄清楚原因。

格式文件

<?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='","' />
  <FIELD ID="2" xsi:type="CharTerm" TERMINATOR='\n' />
 </RECORD>
 <ROW>
  <COLUMN SOURCE="1" NAME="COLUMN1" xsi:type="SQLVARYCHAR" />
  <COLUMN SOURCE="2" NAME="COLUMN2" xsi:type="SQLVARYCHAR" />
 </ROW>
</BCPFORMAT>

CSV

COLUMN1,COLUMN2
"ABC","ABC123456"
"TNT","TNT123456"

查询

SELECT *
FROM OPENROWSET(BULK 'C:\sample.csv',
FORMATFILE='C:\sample.xml',
FIRSTROW = 2) AS a

结果

COLUMN1 COLUMN2
------- ----------
"TNT    TNT123456"

(1 row(s) affected)

如果FIRSTROW更改为1,则结果为:

COLUMN1                COLUMN2
---------------------  ----------
COLUMN1,COLUMN2  "ABC  ABC123456" 
"TNT                   TNT123456"

如果从CSV中删除标题行并将FIRSTROW更改为1,则结果会按预期返回:

COLUMN1 COLUMN2
------- ----------
"ABC    ABC123456" 
"TNT    TNT123456"

由于这是一个随标题一起提供的自动报告,还有其他方法可以解决此问题吗?

6 个答案:

答案 0 :(得分:2)

第一个字段的终止符应该是','而不是'“,”。

替换为以下行,它会起作用:

<FIELD ID="1" xsi:type="CharTerm" TERMINATOR=',' />

原始文件格式会发生什么......

第一列终止于:“,”......这意味着,SQL Server解析第一行,然后读取秒行并获取第一个字段:

COLUMN1,COLUMN2  "ABC

它继续读取并获取第二个字段(记住,我们仍然在文件的第二行):

ABC123456"

它现在有第一行......

然后读取下一行:

"TNT                   TNT123456"

所以当你跳过第一行时,它会跳过第一行,因为你的第一行没有使用引号......

希望有所帮助..

答案 1 :(得分:2)

这里有几个问题:

  1. 我怀疑第一行没有有效的\n。否则,当您更改为FIRSTROW = 1时,SQL Server将不会前两行。

  2. 使用","作为列分隔符适用于除第一列和最后一列之外的所有列。这会在第一列上留下前导",在最后一列上留下尾随"。您可以通过将ROWTERMINATOR更改为"\n来处理后者,但这只有在您还可以向标题行添加尾随"时(在确保存在的过程中)是有效的\n。此时,您还可以确保标题行与所有方面的数据行匹配,因此:

    "COLUMN1","COLUMN2"
    -------------------^ this character has to be \n
    
  3. 老实说,我认为你可以花一周的时间来解决所有这些细节BCPBULK INSERT问题,但仍然没有一个不需要发布的完美解决方案-op动作(例如修剪某些列中的前导/尾随"字符)。我的建议:花20分钟在C#中编写解析器,自动更正这些文件 - 删除标题行,确保正确的分隔符到位,删除所有愚蠢的"等等,然后SQL Server才能看到文件。清理文件比你现在跳过的箍要麻烦得多。我确定有这方面的解决方案,但IIRC你已经和它搏斗了很长时间......

答案 2 :(得分:1)

另外,请检查.CSV文件的字符编码。它可能是带有三字节签名的UTF-8。 bcp.exe似乎不理解这种格式。确保您的文件以符号字节ASCII格式保存。您也可以尝试指定UTF-8代码页参数(-C 65001),但AFAIR它不适用于某些较旧的SQL Server版本。

编辑: 当导入带有UTF-8签名的.csv文件时,我发现了同样的问题:第一个数据行(带有签名的数据)被跳过。

答案 3 :(得分:0)

<?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="\""/>
  <FIELD ID="2" xsi:type="CharTerm" TERMINATOR="\",\"" />
  <FIELD ID="3" xsi:type="CharTerm" TERMINATOR="\"\r\n"/>
 </RECORD>
 <ROW>
  <COLUMN SOURCE="2" NAME="COLUMN1" xsi:type="SQLVARYCHAR" />
  <COLUMN SOURCE="3" NAME="COLUMN2" xsi:type="SQLVARYCHAR" />
 </ROW>
</BCPFORMAT>

此处提供的BCP格式文件将有助于跳过基本上可以忽略“COLUMN1值”开头的第一个字段。记录上的FIELD1由单个双引号终止并将被跳过。字段2由以下字符结束:双引号后跟一个逗号后跟双引号\“,\”(这里的反斜杠用于转义双引号字符)。字段3由双引号后跟CR(回车)后跟LF(lineFeed)终止)这是\“\ r \ n。

系统读取第一个字段直到双引号并跳过它,读取第二个字段直到\“,\”并将其分配给COLUMN1,读取第三个字段直到\“\ r \ n并分配给COLUMN2并在下一条记录上移动,依此类推。基本上,这应该可以干净地处理您的CSV文件供稿。

答案 4 :(得分:0)

在XML格式文件中放入false字段"0",但不要映射任何其他列。

<FIELD ID="0" xsi:type="CharTerm" TERMINATOR='"' />

这对我有用,使用以下查询:

SELECT  * FROM OPENROWSET( BULK 'C:\sample.txt', FIRSTROW = 0,
   FORMATFILE = 'C:\sample.xml' ) AS a;

答案 5 :(得分:0)

我有完全相同的问题,CSV数据的标题也需要有双引号(即使您尝试跳过BCP或Bulk插入时的第一行,这是令人难以置信的)或者您只是删除标题(首先您的CSV文件的行):

&#34; COLUMN1&#34;&#34; COLUMN2&#34; &#34; ABC&#34;&#34; ABC123456&#34; &#34; TNT&#34;&#34; TNT123456&#34;