如何解决嵌入式文本限定符问题,同时将数据导出到CSV平面文件?(How to fix the emb

2019-07-19 17:36发布

RFC 4180:

RFC 4180定义Common Format and MIME Type for Comma-Separated Values (CSV) Files 。 其中一个要求RFC 4180表述为如下。 这是一点#7在RFC链接。

If double-quotes are used to enclose fields, then a double-quote
appearing inside a field must be escaped by preceding it with
another double quote.  For example:

"aaa","b""bb","ccc"

SQL Server 2000中:

DTS Export/Import WizardSQL Server 2000似乎符合上述标准,即使RFC 4180本身似乎已在2005年10月出版的唯一。 我使用下面的说明SQL Server 2000版本。

Microsoft SQL Server  2000 - 8.00.2039 (Intel X86) 
May  3 2005 23:18:38 
Copyright (c) 1988-2003 Microsoft Corporation
Standard Edition on Windows NT 5.0 (Build 2195: Service Pack 4)

SQL Server 2012中:

SQL Server Import and Export WizardSQL Server 2012不会从表中根据RFC 4180,我使用下面的说明SQL Server 2012的版本中定义的标准将数据导出到CSV文件。

Microsoft SQL Server 2012 - 11.0.2316.0 (X64) 
Apr  6 2012 03:20:55 
Copyright (c) Microsoft Corporation
Enterprise Edition (64-bit) on Windows NT 6.1 <X64> (Build 7601: Service Pack 1) (Hypervisor)

问题模拟:

下面是我都SQL Server 2000SQL Server 2012的跑进来一个样本。 我跑到下面的查询创建一个表并插入一些记录。 该ItemDesc列有在它双引号的数据。 我的目的是将数据从这两SQL Server版本使用其内置的数据导出向导导出和比较生成的CSV文件。

CREATE TABLE dbo.ItemInformation(
    ItemId nvarchar(20) NOT NULL,
    ItemDesc nvarchar(100) NOT NULL
) 
GO

INSERT INTO dbo.ItemInformation (ItemId, ItemDesc) VALUES ('100338754', 'Crown Bolt 3/8"-16 x 1" Stainless-Steel Hex Bolt');
INSERT INTO dbo.ItemInformation (ItemId, ItemDesc) VALUES ('202255836', 'Simpson Strong-Tie 5/8" SSTB Anchot Bolt');
INSERT INTO dbo.ItemInformation (ItemId, ItemDesc) VALUES ('100171631', 'Grip-Rite #11 x 1-1/2" Electro-Galvanized Steel Roofing Nails');
INSERT INTO dbo.ItemInformation (ItemId, ItemDesc) VALUES ('202210289', 'Crown Bolt 1/2" x 3" "Zinc-Plated" Universal Clevis Pin');
INSERT INTO dbo.ItemInformation (ItemId, ItemDesc) VALUES ('100136988', 'Tapcon 3/16" x 1-3/4" Climaseal Steel "Flat-Head" Phillips Concrete Anchors (75-Pack)');
INSERT INTO dbo.ItemInformation (ItemId, ItemDesc) VALUES ('203722101', 'KwikTap 3/16" x 2-1/4" "Flat-Head" Concrete Screws (100-Pack)');
GO

DTS Export/Import WizardSQL Server 2000 ,我用下面的设置,以将数据导出到CSV文件。 我该文件的名称保存SQLServer2000_ItemInformation.csv

SQL Server Import and Export WizardSQL Server 2012 ,我用下面的设置,以将数据导出到CSV文件。 我该文件的名称保存SQLServer2012_ItemInformation.csv

下面是使用超越比较两个文件之间的比较。 左侧包含所产生的文件SQL Server 2000和右侧包含生成的文件SQL Server 2012 。 你可以看到,从左侧文件SQL Server 2000包含附加双引号中的数据列,以弥补嵌入式引号。 这符合规定的标准RFC 4180 ,但它显然是从生成的文件中缺少SQL Server 2012

搜索网站:

我搜索在网络上此问题,并发现了下面的链接。 以下是Microsoft Connect上的错误报告。 所有这些问题似乎都与导入文件,但有关数据导出什么。 因为所有这些错误已被关闭Fixed

  • SSIS平面文件分析器不读取嵌入文本数据列分隔符
  • 平面文件连接管理器无法处理文本分隔符的CSV文件
  • 在平面文件嵌入式报价导入失败
  • BUG:平面文件连接管理:多个字符的文本限定符不加载所有数据

后下MSDN上的博客指出,变化已经在SQL Server 2012中已取得相对于Flat file source supports embedded qualifiers and a variable number of columns per row

  • SSIS -什么在SQL Server Denali的新

在MSDN博客另一个后国家下的部分相同的Embedded Qualifiers

  • 迪纳利平面文件源代码更改

解决方法,我知道的:

我知道一种解决方法通过编写一个查询,将取代所有双引号(来解决这个问题"有两个双引号在我的专栏的数据() "" ),使导出的文件将结束与正确的嵌入式预选赛的数据。这将避免直接从表中把数据原样。

我的问题:

  • 我不知道这个问题已经真正固定在SQL Server 2012 。 有这个问题一直只固定importing已嵌入文本预选赛和文件not用于exporting数据到CSV?

  • 也许,我清楚地做错了什么和缺少明显。 可能有人请向我解释什么,我做错了什么?

微软连接:

我提出了关于微软连接网站的错误报告得到他们的反馈。 这里是链接到错误报告。 如果你认为这是一个错误,请访问以下链接投票了对Microsoft Connect网站。

导出为CSV在嵌入式文本识别符不符合RFC 4180

Answer 1:

我不会提供这个答案,只是你辛辛苦苦来记录它,它一直upvoted用了一个月后,没有回答。 所以,在这里去。 你唯一的选择似乎是改变数据或更改的工具。

也许,我清楚地做错了什么和缺少明显。 可能有人请向我解释什么,我做错了什么?

当工具被打破,供应商并不关心,这是错误的继续努力。 现在是时候进行切换。 你投入了大量的精力来研究它究竟是如何打破,证明它违反不仅RFC但工具本身的早期版本。 多少更多的证据,你需要什么?

CSV是一个船锚过。 如果可以选择,你就要去使用一个普通的分隔符的文件格式更好。 对于许多应用程序,制表符分隔好。 最好的分隔符IMO是“\”,因为这个角色在英文文本的地方。 (在另一方面,它也不会包含Windows路径名的数据。)

CSV有两个问题作为交换格式。 首先,这是不是所有的标准; 不同的应用程序识别不同的版本,无论RFC可能会说。 第二个(相关的)是,它并不构成CS方面的规则语言 ,这就是为什么它不能被解析为正则表达式。 与比较^([^\t]*\t)*[\t]*$为制表符分隔的线。 该CSV的定义复杂的实际含义是(见上文)的工具相对缺乏处理他们和他们的倾向是不相容的,尤其是在凌晨。

如果你给CSV和DTS引导,你有很好的选择,其中之一是bcp.exe 。 它的速度非常快,而且安全,因为微软还没有被诱惑更新了多年。 我不知道很多关于DTS,但如果你要使用它的自动化,IIRC有调用外部公用设施的一种方式。 要小心的是,这bcp.exe没有错误状态返回到shell可靠。

如果你决定使用DTS与CSV坚持,那么真的是你最好的剩下的选择是写一个适当准备的数据来看。 我想,如果被逼到那个角落,创建一个名为,说:“DTS2012CSV”模式,这样我就可以写select * from DTS2012CSV.tablename ,给别人谁在乎一个战斗的机会去了解它(因为您将其记录下来,不会吧,在视图中的文本注释?)。 如果需要的话,其他人可以复制其技术用于其他破碎提取物。

HTH。



Answer 2:

我知道这是两岁,但我现在也有这个问题,因为我们需要使用SQL Server 2008,我们有(不要问)的合同。 通过这个问题,看完后,我意识到我需要做更换建议,但我去的时候做,在查询时,我碰到了截断的问题,因为在查询本身使用replace()函数将文本转换为VARCHAR(8000),在默认情况下。

然而,我发现我可以用在DB源和平面文件对象之间的派生列的步骤做同样的事情。 例如,我有一个名为“SHORT_DESCRIPTION,”可能有它的报价列,所以我只是用下面的函数的表达式,并选择在派生列“替换SHORT_DESCRIPTION”:

REPLACE(short_description,"\"","\"\"")

这似乎已经解决了这个问题对我来说。



Answer 3:

通常情况下,第一和最后一个名字是在同一领域和格式(姓,)。 这需要如果你使用任务 - >导出数据马上(你有更多的选择不是通过SSIS)的数据库中的文本资格,你需要到CSV导出为逗号分隔的文件。

这将有助于在需要双引号的非null选定字段...

CASE WHEN NOT PersonName IS NULL AND LEN(PersonName) > 0 THEN QUOTENAME(PersonName, '"') ELSE NULL END as 'PersonName'

结果:

PERSONNAME

“柯林斯,ZACKERY E”



文章来源: How to fix the embedded text qualifier issue while exporting data to CSV flat file?