我正在使用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"
由于这是一个随标题一起提供的自动报告,还有其他方法可以解决此问题吗?
答案 0 :(得分:2)
第一个字段的终止符应该是','而不是'“,”。
替换为以下行,它会起作用:
<FIELD ID="1" xsi:type="CharTerm" TERMINATOR=',' />
原始文件格式会发生什么......
第一列终止于:“,”......这意味着,SQL Server解析第一行,然后读取秒行并获取第一个字段:
COLUMN1,COLUMN2 "ABC
它继续读取并获取第二个字段(记住,我们仍然在文件的第二行):
ABC123456"
它现在有第一行......
然后读取下一行:
"TNT TNT123456"
所以当你跳过第一行时,它会跳过第一行,因为你的第一行没有使用引号......
希望有所帮助..
答案 1 :(得分:2)
这里有几个问题:
我怀疑第一行没有有效的\n
。否则,当您更改为FIRSTROW = 1
时,SQL Server将不会前两行。
使用","
作为列分隔符适用于除第一列和最后一列之外的所有列。这会在第一列上留下前导"
,在最后一列上留下尾随"
。您可以通过将ROWTERMINATOR
更改为"\n
来处理后者,但这只有在您还可以向标题行添加尾随"
时(在确保存在的过程中)是有效的\n
。此时,您还可以确保标题行与所有方面的数据行匹配,因此:
"COLUMN1","COLUMN2"
-------------------^ this character has to be \n
老实说,我认为你可以花一周的时间来解决所有这些细节BCP
和BULK 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;