【问题标题】:BULK INSERT / OPENROWSET FormatFile Terminator for CSV file with , (comma) in the dataBULK INSERT / OPENROWSET CSV 文件的格式文件终止符,数据中带有 ,(逗号)
【发布时间】:2012-07-15 10:17:56
【问题描述】:

我为我的百万行 CSV 编写了一个很好的导入,效果很好(使用 OPENROWSET BULK(我没有使用 BULK INSERT,因为我需要与其他一些列交叉连接)。格式文件使用逗号作为终结者。

这是我用来开发的 CSV 示例:

Reference, Name, Street
1,Dave Smith, 1 Test Street
2,Sally SMith,1 Test Street

一旦我得到它的工作,有人提醒我数据本身可能有一个逗号,哎呀!!!!

Reference, Name, Street
"1","Dave Smith", "1 Test Street"
"2","Sally Smith","1,Test Street" <-comma in street

人们如何使用 FormatFiles 处理数据中带有逗号的 CSV? (或者我只是说文件必须用TAB分隔)?

【问题讨论】:

  • 我知道的大多数导入实用程序都会忽略字符串中的逗号(或其他分隔符)——他们认为它是字符串的一部分。除此之外,如果最终在字符串中出现制表符(在引号之间)会发生什么?你最终会遇到同样的问题。看看你能不能指定字符串分隔符,你可能会没事的。

标签: sql sql-server c#-4.0 bulkinsert openrowset


【解决方案1】:

数据字段中的分隔符是分隔文件的常见问题。解决此问题的一些常见策略包括:

  1. 重新创建数据文件,在将数据字段写入文件之前将所有出现的定界符从数据字段中去除:这会消除 OPENROWSET 错误,但不会保持数据的完整性。
  2. 使用不同的分隔符重新创建数据文件:根据我的经验,制表符分隔符是更好的选择。在数据中遇到制表符比遇到逗号要少见。但这肯定不是闻所未闻的。我也看到过数据中的标签。
  3. 用双引号将数据字段括起来:这需要对 XML 格式文件进行一些调整。

手动编辑数据文件可能适用于上述任何选项。但这可能很乏味,尤其是对于大文件。 (只需在 Notepad.exe 中打开几个 GB 的文件是一种耐心练习。)实际上,您希望作者为您重新创建它。选项 #1 应该始终“有效”。但同样,您可能无法忍受数据完整性问题。选项 #2 可能适用于许多情况,但它不是万无一失的。选项#3 也不是万无一失的(它总是可能 在数据字段中有一个分隔符),但它几乎是尽可能接近的。此外,它还保留了数据完整性。

这是您的 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="5"/>
  <FIELD ID="2" xsi:type="CharTerm" TERMINATOR='","' MAX_LENGTH="128" COLLATION="SQL_Latin1_General_CP1_CI_AS"/>
  <FIELD ID="3" xsi:type="CharTerm" TERMINATOR='"\r\n' MAX_LENGTH="128" COLLATION="SQL_Latin1_General_CP1_CI_AS"/>
 </RECORD>
 <ROW>
  <COLUMN SOURCE="1" NAME="Reference" xsi:type="SQLVARYCHAR"/>
  <COLUMN SOURCE="2" NAME="Name" xsi:type="SQLVARYCHAR"/>
  <COLUMN SOURCE="3" NAME="Street" xsi:type="SQLVARYCHAR"/>
 </ROW>
</BCPFORMAT>

注意 FIELD TERMINATOR:我使用单引号将 "," 标识为终止符,将 "\r\n 标识为行终止符(第 3 列终止符)。我做了一个有根据的猜测,NameStreet 最多 128 个字符——根据需要进行编辑。

问题:

  1. OPENROWSET() 查询将返回 Reference 并带有前导 " 双引号字符。正因为如此...
  2. Reference 不能作为 INT(或 SMALLINT、BIGINT 等)返回。它以 VARCHAR (xsi:type="SQLVARYCHAR") 的形式返回

对于提供的特定数据示例,我将删除 Reference 数据字段中的双引号,调整 XML 格式文件以使 FIELD ID="1" 具有 TERMINATOR=',"',并进一步调整 XML 格式文件以使 @ 987654334@ 有xsi:type="SQLINT"

有关其他信息,此博客文章可能会有所帮助:Getting Started With OPENROWSET and the BULK Rowset Provider - Part 2

【讨论】:

    【解决方案2】:

    如果您的字段终止符可以出现在数据中,那么最好使用 TAB 或 PIPE 分隔符(或任何适用于您的数据的)。

    如果数据中出现终止符,则将其解释为 终止符,而不是数据,并且该字符之后的数据是 解释为属于下一个字段或记录。所以, 仔细选择你的终结者,以确保它们永远不会出现 在您的数据中

    http://msdn.microsoft.com/en-us/library/ms191485.aspx

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-02-28
      • 1970-01-01
      • 1970-01-01
      • 2014-02-01
      • 1970-01-01
      • 2016-11-29
      • 1970-01-01
      相关资源
      最近更新 更多