Sql server 如何解决将数据导出到CSV平面文件时嵌入的文本限定符问题? RFC 4180:
为逗号分隔值(CSV)文件定义Sql server 如何解决将数据导出到CSV平面文件时嵌入的文本限定符问题? RFC 4180:,sql-server,ssis,sql-server-2000,sql-server-2012,Sql Server,Ssis,Sql Server 2000,Sql Server 2012,为逗号分隔值(CSV)文件定义通用格式和MIME类型。RFC 4180的要求之一如下所述。这是RFC链接中的第7点 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 Ser
通用格式和MIME类型
。RFC 4180
的要求之一如下所述。这是RFC链接中的第7点
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:
SQL Server 2000
中的DTS导出/导入向导
似乎符合上述标准,尽管RFC 4180本身似乎仅于2005年10月发布。我正在使用以下SQL Server 2000版本
SQL Server 2012:
SQL Server 2012
中的SQL Server导入和导出向导
未根据RFC 4180中定义的标准将数据从表导出到CSV文件。我使用的是以下SQL Server 2012版本
在SQL Server 2000的DTS导出/导入向导中,我使用以下设置将数据导出到CSV文件。我以名称SQLServer2000\u ItemInformation.csv
保存了该文件
在SQL Server 2012
中的SQL Server导入和导出向导
上,我使用以下设置将数据导出到CSV文件。我以名称SQLServer2012\u ItemInformation.csv
保存了该文件
下面是使用Beyond Compare对两个文件进行的比较。左侧包含由SQL Server 2000
生成的文件,右侧包含由SQL Server 2012
生成的文件。您可以注意到,SQL Server 2000的左侧文件包含额外的双引号,以补偿数据列中嵌入的引号。这符合RFC 4180中指定的标准,但由SQL Server 2012生成的文件中显然缺少该标准
网上搜索:
我在网上搜索了这个bug,找到了以下链接。以下是有关Microsoft Connect的错误报告。所有这些问题似乎都与导入文件有关,而与导出数据无关。所有这些bug都已关闭,已修复
下面MSDN博客上的帖子指出,SQL Server 2012中对平面文件源代码支持嵌入式限定符和每行可变列数所做的更改
MSDN博客上的另一篇文章在嵌入式限定符
一节中说明了同样的情况
我知道的解决方法:
我知道一种解决方法,可以通过编写一个查询来解决此问题,该查询将我的列数据中的所有双引号(“
)替换为两个双引号(”
)这样导出的文件将以正确的嵌入限定符数据结束。这将避免直接从表中提取数据
我的问题是:
- 我不知道这个问题是否在
SQL Server 2012
中得到了真正的解决。这个问题是否只在导入带有嵌入式文本限定符的文件时得到了解决,而不是在将数据导出到CSV时得到了解决
- 很可能,我显然做错了什么,漏掉了显而易见的东西。有人能给我解释一下我做错了什么吗
Microsoft Connect:
我已在Microsoft Connect网站上提交了一份错误报告,以获取他们的反馈。这是错误报告的链接。如果您同意这是一个错误,请访问下面的链接在Microsoft Connect
网站上投票
我不会给出这个答案,除非你非常努力地将它记录下来,一个月后它被升级了,没有答案。所以,现在开始。你唯一的选择似乎是更改数据或更改工具
很可能,我显然做错了什么,漏掉了显而易见的东西。有人能给我解释一下我做错了什么吗
当工具损坏且供应商不关心时,继续尝试是错误的。是时候切换了。你花了大量精力研究它是如何损坏的,并证明它不仅违反RFC,而且违反了工具自己的先前版本。你还需要多少证据
CSV也是一种船锚。如果您有选择权,最好使用普通的分隔文件格式。对于许多应用程序,制表符分隔很好。最好的分隔符IMO是“\”,因为该字符在英文文本中没有位置。(另一方面,它不适用于包含Windows路径名的数据。)
CSV作为一种交换格式有两个问题。首先,它不完全是标准的;不同的应用程序可以识别不同的版本,不管RFC怎么说。第二(和相关的)是它在CS术语中不构成正则语言,这就是为什么它不能被解析为正则表达式。与^([^\t]*\t)*[\t]相比*$
用于制表符分隔的行。CSV定义的复杂性的实际含义是(见上文)处理它们的工具相对缺乏,并且它们往往不兼容,特别是在凌晨
如果你启动CSV和DTS,你会有很好的选择,其中一个是bcp.exe
。它非常快而且安全,因为微软已经多年没有尝试过更新它了。我对DTS了解不多,但如果你不得不使用它来实现自动化,IIRC有一种调用外部实用程序的方法。不过要小心,bcp.exe代码>不会可靠地向外壳返回错误状态
如果你决定使用DTS并坚持使用CSV,那么你剩下的最佳选择就是编写一个视图,为它适当地准备数据。如果回到那个角落,我会创建一个名为“DTS2012CSV”的模式,这样我就可以从DTS2012CSV.tablename
,g中编写select*
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)
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)
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
REPLACE(short_description,"\"","\"\"")
CASE WHEN NOT PersonName IS NULL AND LEN(PersonName) > 0 THEN QUOTENAME(PersonName, '"') ELSE NULL END as 'PersonName'