C# 使用Filehelpers,将大型CSV文件导入SQL2014表

C# 使用Filehelpers,将大型CSV文件导入SQL2014表,c#,sql-server,filehelpers,C#,Sql Server,Filehelpers,CSV文件以逗号分隔,包含嵌入的分隔符和引号。有些字段有开头和结尾引号,有些字段没有 第一条记录处理得很好,但第二条记录处理得不好。正如您所看到的,该字段似乎有一个前导引号,但它实际上是嵌入的。字段5没有尾随引号。导入的结果将在字段5和6中留空,并将字段5数据(粗体)推送到字段7中,这将在稍后的过程中导致最大字段长度冲突 Filehelpers中是否有一个属性设置,我可以使用它来处理包含以下粗体字字段的记录,以便该记录正确导入每个字段?CSV文件是从外部源接收的,因此我无法控制提要 AT2M-2

CSV文件以逗号分隔,包含嵌入的分隔符和引号。有些字段有开头和结尾引号,有些字段没有

第一条记录处理得很好,但第二条记录处理得不好。正如您所看到的,该字段似乎有一个前导引号,但它实际上是嵌入的。字段5没有尾随引号。导入的结果将在字段5和6中留空,并将字段5数据(粗体)推送到字段7中,这将在稍后的过程中导致最大字段长度冲突

Filehelpers中是否有一个属性设置,我可以使用它来处理包含以下粗体字字段的记录,以便该记录正确导入每个字段?CSV文件是从外部源接收的,因此我无法控制提要

AT2M-2471-3,,“1178”,AccuTemp,48英寸实心切割板(必须与AT2A-2630-3或AT2A-2630-22一起订购),ea,“10.00”,“0.00000”,“207.00”,“93.41”,“0.00”,“0.00”,“0.00”,“0.00”,“0.00”,ATCUT,,“1”,每个,“切割板,设备安装”,AccuTemp,,“假”,“85”,“0”,“0”,“baab3369-bcad-453e-9867-921e4af1203c”,“AccuTemp,,,”,AccuTemp,,“,”,“e0fb1dfb-c00d-dd11-a23a-00304834a8c9”、“bcd6e7a0-be0d-dd11-a23a-00304834a8c9”

AT2M-2877-1,,“1178”,AccuTemp,“U”通道,用于连接两个29英寸A深度的网格,,ea,“4.00”,“0.00000”,“104.00”,“46.93”,“0.00”,“0.00”,“0.00”,“0.00”,“0.00”,“0.00”,“0.00”,AT2M,,“1”,每个,AccuTemp,“,”假“,”85“,”0”,“f7d56cb1-b2ab-40c7-b7e5-551B4D1023”,“E31DFB-c00d-DD0033A-A28C049”bcd6e7a0-be0d-dd11-a23a-00304834a8c9“

以下是SQL表结构,没有索引:

    CREATE TABLE [dbo].[rawdata](
        [Model Number] [varchar](50) NULL,
        [User Stock Model Number] [varchar](50) NULL,
        [Vendor Number] [varchar](50) NULL,
        [Vendor Name] [varchar](50) NULL,
        [Specification] [varchar](max) NULL,
        [Vendor Pack] [varchar](50) NULL,
        [Selling Unit] [varchar](50) NULL,
        [Weight] [varchar](50) NULL,
        [Cube] [varchar](50) NULL,
        [List Price] [varchar](50) NULL,
        [Net Price] [varchar](50) NULL,
        [Height] [varchar](50) NULL,
        [Width] [varchar](50) NULL,
        [Depth] [varchar](50) NULL,
        [Deal Net] [varchar](50) NULL,
        [Picture Name] [varchar](150) NULL,
        [Blank Column] [varchar](50) NULL,
        [Vendor to Stock] [varchar](50) NULL,
        [Priced By] [varchar](50) NULL,
        [Category] [varchar](75) NULL,
        [Vendor Nickname] [varchar](50) NULL,
        [User Vendor Name] [varchar](50) NULL,
        [Configurable?] [varchar](50) NULL,
        [Category Values] [varchar](max) NULL,
        [Freight Class] [varchar](50) NULL,
        [Vendor FOB] [varchar](50) NULL,
        [Ship from Zip] [varchar](50) NULL,
        [Model Apply] [varchar](50) NULL,
        [Picture Link] [varchar](50) NULL,
        [Category Code] [varchar](50) NULL,
        [Vendor Short Name] [varchar](50) NULL,
        [Cutsheet Name] [varchar](150) NULL,
        [Cutsheet Link] [varchar](50) NULL,
        [Product ID] [varchar](50) NULL,
        [Vendor ID] [varchar](50) NULL
    ) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
我为具有以下属性的表创建了类: [分隔符记录(“,”)] [第一(1)条]

}

以下是C#代码:


问题是CSV无效,只有在字段被引用时才能转义引号

值:

,""U"" channel for connecting two 29"" A Depth griddles,
要正确解析,它必须是

,"""U"" channel for connecting two 29"" A Depth griddles",
如何从规范字段中删除引用的字段

  public string Specification;

正如@MarcosMeli所提到的,问题在于这是一个无效的CSV文件。而不仅仅是一个字段。即使是您认为有效的行也没有真正起作用。似乎创建此CSV文件的人在哪些字段应该是文本限定的(即“引用”)方面做了反向操作它们有文本限定的数字字段和非限定的文本字段

第1行工作的原因是文本限定查看字段的第一个和最后一个字符。在第1行中,转义引号(即双引号)不是第一个字符,所以我怀疑它是作为重复的双引号导入的。但是在第2行中,该字段的开始文本被引用,因此第一个字符是引号,然后他们通过复制双引号来转义。这是非常草率的做法,甚至现在让FileHelper使用它也没有多少信心在这种情况下,它将继续正常工作,特别是如果非文本限定的文本字段中曾经有逗号。在这种情况下,它将再次导致字段中出现意外的变化。我知道您说过CSV文件来自外部源,您无法控制它,但您确实需要尝试修复它,因为它完全错误。这是错误的任何系统中产生的bug都需要修复

目前,您可以将所有文本字段设置为非文本限定字段。但是,您可能需要添加一个步骤,用一个双引号替换所有双引号


撇开数据格式问题不谈,在不影响FileHelpers的情况下,因为它看起来确实像一个有趣而有用的库,我要说的是,您不需要FileHelpers来逐行读取文本文件(最小内存占用)并将其批处理到SQL Server中。事实上,您可以做到所有这些,另外:

  • 跳过拥有单独的暂存表(即
    [rawdata]
    )的步骤,而是直接将行发送到同步存储过程中
  • 在应用层中执行基本数据类型验证,并发送强类型数据行(而不是传入所有
    VARCHAR
    /
    NVARCHAR
    字段)
如何实现?通过使用表值参数并使用
IEnumerable
方法(而不是
DataTable
方法)将其传入。我在这里的几个答案中详细介绍了该技术:

,"""U"" channel for connecting two 29"" A Depth griddles",
  public string Specification;