使用字段中的引号将CSV导入SQL Server的简便方法

时间:2018-11-16 16:29:36

标签: sql-server csv ssms

我正在尝试将CS​​V文件(包括字段中的逗号和引号)导入SQL Server数据库。在线上有大约一百万个问题和主题,但没有一个真正有效。我已经了解到,当涉及到CSV时,存在一些稍微不同的标准,但是SSMS似乎都不能导入,我觉得确实应该有一种方便的方法。

文件包含自由文本字符串,它们在字段中使用双引号和逗号。

这是我正在使用的测试CSV文件:

"Value 1","Notes"
""8-pooln" grupp 7:6 To11:13","As extracted"
"""8-pooln"" grupp 7:6 To11:13","With escaped quotes"
"""""""""""8-pooln"""""""""""""""" grupp 7:6 To11:13","With loads of quotes"

我使用了第三方程序将数据提取到CSV。因此,第一条记录是我从该程序中获得的记录。根据某些站点的介绍,您需要在字段中通过添加另一个双引号来转义双引号,这就是您在记录2中看到的。最后一个双引号只是包含了很多双引号用于测试。我还使用另一个应用程序将文件验证为CSV,并通过了第二和第三条记录。

通过使用SSMS导入向导,我得到:

_Value_1_,_Notes_
8-pooln" grupp 7:6 To11:13,As extracted
8-pooln"" grupp 7:6 To11:13,With escaped quotes
8-pooln"""""""""""""""" grupp 7:6 To11:13,With loads of quotes

因此,无论有多少双引号都始终被忽略。我还没有找到可以完全改变此设置的设置。

我还尝试过手动编写SQL命令,例如:

BULK INSERT CSVTest
FROM 'c:\csvtest.txt'
WITH
    (FIELDTERMINATOR = ',',
     ROWTERMINATOR = '\n')

哪个给了我们

Value_1,Notes
"Value 1","Notes"
""8-pooln" grupp 7:6 To11:13","As extracted"
"""8-pooln"" grupp 7:6 To11:13","With escaped quotes"
"""""""""""8-pooln"""""""""""""""" grupp 7:6 To11:13","With loads of quotes"

它仅将逗号和换行符识别为任何类型的控制字符,并且似乎没有任何其他行可以添加以对其进行修复。

最后,我找到了一些解决方案,您可以在其中编写“格式文件”,基本上可以在其中手动定义每个列的列定界符。这可能会工作,但是我对一个文件和大约20个文件有50多个列。

我还在SSMS导入向导的设置中找到了一种可能的解决方案,但它适用于旧版本,并且看起来不再存在。

要澄清:

  • 字段中包含逗号和双引号,因此必须使用双引号来打开和关闭字段。我宁愿完全不更改任何内容(例如从双引号到单引号),因为我不确切知道值的含义。
  • 大约有20个文件,一个包含95000条记录和50多个列。创建格式文件似乎不合理。
  • 这实际上并不是格式错误的文件。直观上来说,SSMS实际上应该能够在不进行任何修复的情况下将其导入。也许我可以手动编辑CSV文件以使其符合标准(就像我对测试文件中的第二条记录所做的那样)。

在这一点上,我很高兴了解为什么它不起作用或者为什么我的问题似乎很独特。

1 个答案:

答案 0 :(得分:0)

我不确定是否可以使用SSIS,但是如果这样,导入文本字段中带引号的数据将相当容易。此过程的概述如下。

  • 创建到目标表所在的SQL Server实例的OLE DB连接。 可以通过在“连接管理器”窗口中右键单击,选择 New Connection ... ,然后选择OLE DB选项来完成。配置将数据加载到的登录凭据和初始目录。
  • 接下来创建平面文件连接管理器。对于“文件名”字段,导航至现有文件夹并选择示例数据文件。如果看不到文件,请更改为文件资源管理器中所有文件的文件扩展名。选择Delimited作为“格式”字段,然后检查“第一个数据行中的列名称”选项是否适用于您的文件。适当设置标题行定界符。从您的示例来看,我猜您将使用回车/行字段组合,即{CR}{LF}值。
  • 在“列”窗格上,相应地设置行定界符,该定界符也似乎是示例中的{CR}{LF}。对于列定界符,请使用,。这将应用于文件中的所有列,因此您无需为每个字段设置此值。您的问题我无法完全确定,但是如果,分隔了所有字段,请使用此选项,否则请输入Mixed作为列定界符。此选项可能不会出现在下拉菜单中,但将其绑定将允许您对每一列使用不同的定界符。详情请见下文

  • 在“高级”窗格中,为列添加名称,数据类型和长度。如果不确定哪种SSIS数据类型对应于SQL Server,请参见此link中的映射表,该映射表显示了哪些数据类型相互关联。如果您使用了上面的Mixed选项,则可以在ColumnDelimiter字段中为每一列设置定界符。您也可以在此处输入值。例如,如果字段将始终由某些字符组合分隔,则也可以使用。

  • 创建连接管理器后,创建一个数据流任务,并在其中添加平面文件源组件。使用刚刚为该组件的连接管理器创建的连接管理器。

  • 接下来添加OLE DB或SQL Server目标。我发现SQL Server目标往往会表现得更好,但是当然这在不同的环境中会有所不同。使用为目标SQL Server实例创建的OLE DB连接管理器,并映射“映射”窗格上的列。将平面文件源连接到SQL Server目标,现在您可以将数据从源文件加载到表中。

  • 如果要定期执行此操作,请考虑将其设置为SQL Agent作业。您可以在此过程here中找到更多详细信息。