如何在 SQL Server Management Studio 中以“真实”CSV 格式获取导出输出?

Posted

技术标签:

【中文标题】如何在 SQL Server Management Studio 中以“真实”CSV 格式获取导出输出?【英文标题】:How to get export output in "real" CSV format in SQL Server Management Studio? 【发布时间】:2011-09-01 04:26:23 【问题描述】:

我有一个正在 SQL Server Management Studio 中运行的查询(连接到 SQL Server 2005 数据库)。我想以 CSV 格式导出数据。不是想要的 CSV 格式,您只需在每列之间添加一个逗号,而是“真正的”CSV 格式,您可以在字符串周围加上引号。这样您就可以导出包含逗号或引号的数据。

我看到的所有示例都仅限于想要的格式。我不知道引用字符串的选项在哪里。

如果 SSMS 真的无法做到这一基本壮举,还有其他工具可以轻松做到吗?我不想每次需要数据转储时都编写 C# 程序。

【问题讨论】:

因为太烦我了,所以我自己编写了一个程序,使用合适的 CSV 写入器:github.com/deeja/SQLtoCSV/releases 这个问题怎么还没有修复... 引用封装现在是 2016 年 SSMS 中的 default behaviour。 【参考方案1】:

我想提出一种替代方法。我在 SO 中有这个问题的书签。在很多答案和cmets中投票。但是,当我需要执行从 SQL Management Studio 中的查询导出 CSV 文件的平庸任务时,它总是一团糟。

最简单的解决方案是使用其他工具,例如免费的Dbeaver。

    下载Dbeaver多平台数据库工具(有一个便携版本,如果您的机器没有管理员权限也可以使用)。 运行它并创建一个新的 SQL Server 连接。 打开一个新的“Sql 编辑器”标签 点击箭头执行查询 右键单击结果网格并选择“导出数据”并选择 CSV 瞧!现在您有了一个格式正确的 CSV 文件。

没什么神秘的。无需重新启动。它只是工作。

额外提示:您甚至可以在不先进行选择的情况下导出数据。右键单击表/数据库,您将找到导出数据选项。

【讨论】:

如果您希望文本字段中的 CR/LF 被空格替换,DBeaver 仍然存在一些小问题。虽然 .csv 文件在 Excel 中打开时可能呈现正常,但在 notepad++ 中打开时,行在 CR/LF 上显示为拆分。显然它保留了这些特殊字符。如果您希望将它们替换为空格,请使用 SSMS v18 并勾选“工具”>“选项”>“查询结果”>“SQL Server”>“结果到网格”>“复制或保存结果时包括列标题”。 @owl7 这是 CSV 文件的正确行为。带有换行符的行用引号括起来,适当的 CSV 阅读器可以正确解析它们。原始数据没有改变,换行符将显示在任何文本编辑器中。【参考方案2】:

我能够使用 Matthew Walton 的回答导出我的一个结果集,但是我的另一个结果集无法正常工作。我正在使用我的 sql 数据中的 xml 数据,所以我不能使用逗号分隔或制表符分隔的输出。

我通过使用一个利用 pandas 的基本 Python 脚本解决了这个问题。 Pandas 有数据框对象,可以干净地存储您的所有数据,然后您可以将该数据框导出到 Excel 工作表中。我用这个链接来帮助我 - https://appdividend.com/2020/04/27/python-pandas-how-to-convert-sql-to-dataframe/

import pandas as pd
import pyodbc
conn = pyodbc.connect(connection_string)
cursor = conn.cursor()
sql_query = pd.read_sql_query(
    '''SELECT TOP (1000) [column_1]
                  ,[column_2]
                  ,[column_3]
                   FROM [My_Table]
                  ''', conn)

df = pd.DataFrame(sql_query, columns=['column_1', 'column_2', 'column_3'])
df.to_excel("exported_data.xlsx", index=False)

【讨论】:

【参考方案3】:

在阅读了答案(尤其是 iacob 的答案)并在较新版本的 SSMS 中尝试了建议的选项之后,我决定深入研究并编译这些选项的全面概述以及它们如何影响导出格式。

将查询结果导出到文件选项

(这是 SSMS v18.4)

未选择任何选项: => 数据导出为“CSV”,但使用分号而不是逗号作为分隔符。 => 包含分号和/或双引号的值正确地用双引号括起来。 => 双引号用 2x 双引号正确转义。 “复制或保存结果时包括列标题” => 就像它所说的那样,只是将列标题添加为第一行。 => 与 iacob 的回答相反,此选项确实将分隔符更改为逗号,并且 不需要用双引号将分号括起来并正确转义双引号。李> “在复制或保存时保留 CR/LF” => 包含换行符的值正确地用双引号括起来并保留换行符。

选择这两个选项似乎可以生成最有用的 CSV 格式,即使它使用分号而不是逗号作为分隔符。

另一个问题是 NULL 值被导出为“NULL”而不是空字段。

结论:

无论选择哪种方法(导出数据任务/导出结果到 CSV)以及选择了哪些选项,似乎仍然没有单一的方法可以使 SSMS 在适当的支持下正确导出到 CSV用于逗号、分号、双引号以及空值。

【讨论】:

我使用的是 18.9.2 版本,它的行为与我描述的一样;行为似乎是特定于版本/区域设置的。【参考方案4】:

由于上面提到的所有设置都没有修复我的 SSMS (SQL Server 2014) 生成的 CSV(也没有导出制表符分隔的文件),我和一位同事制作了一个 converter script (Ruby) 来转换 SSMS CSV转换为可读的 CSV。

它保留原始文件的编码、分隔符和换行符,甚至在最后进行精确字节匹配验证(它从解析的 (!) 输入文件创建一个 SSMS 格式的文件并比较两个文件)。

【讨论】:

我需要对此进行测试,但这似乎正是我们所需要的,而且它已经在 Ruby 中了。太好了!【参考方案5】:

通常我使用这种功能:

CREATE FUNCTION [dbo].[toExport]
(
    @txt varchar(max)

)
RETURNS varchar(max)
AS
BEGIN
    
    return REPLACE(REPLACE(REPLACE(@txt, ';', ','), CHAR(10), ' '), CHAR(13), ' ');

END

在选择中我把它放在这里:

SELECT dbo.toExport( column_name ) AS column_name FROM ....

在 SMSS 2012 中,只需右键单击网格并将结果另存为,或将所有网格 (ctrl-A) 和 ctrl-V 复制到 Excel。

这是管理数据的最简单方法,例如 MS Excel,不会出现列问题。

当然你必须点击Tools -> Options -> Query Results -> Sql Server -> Results to Grid中的“在保存.csv结果时引用包含列表分隔符的字符串”,如果需要,增加Maximum Characters Retrieved

【讨论】:

【参考方案6】:

您可以改为导出为制表符分隔的格式。

【讨论】:

【参考方案7】:

我不知道仅使用 SSMS 无法做到这一点。我知道TOAD 有一个 CSV 选项。不确定它是否是转义格式。如果 SSIS 是一个选项,您可以转换为转义字符串的格式(真正的 CSV),但这不在 SSMS 中。

如果你必须编写一个 C# 程序,我会考虑查询表然后运行查询,因为元数据会提示哪些需要转义。

【讨论】:

【参考方案8】:

SSMS 工具>>选项>>查询结果>> SQL Server>>结果到网格,设置:“保存.csv结果时引用包含列表分隔符的字符串”。

enter image description here

另外,如果逗号不是默认分隔符也很重要(北欧国家等) 控制面板 >> 时钟、语言和区域 >> 区域 >> 其他设置 enter image description here

这也引用了包含换行符的单元格

作为旁注,将这样创建的文件导入 Excel 时,有一些注意事项。 CSV 文件必须通过双击打开(来源:https://superuser.com/questions/180964/how-to-open-semicolon-delimited-csv-files-in-us-version-of-excel)此外,如果 Excel 区域设置使用 ;作为分隔符,必须在 CSV 文件的第一行添加以下内容:

sep=,

【讨论】:

Quote strings containing list separators when saving .csv results 选项在 SSMS v18.2、v18.9.1 和 v18.10 中均不可用。 @Joona 您是否介意更新您的答案以包括您的 SSMS 版本号,此设置可用?【参考方案9】:

截至 2016 年,这是在查询选项中选择以下选项时的默认行为:

列用逗号分隔,包含逗号的字段用双引号括起来。

【讨论】:

【参考方案10】:

很遗憾,该选项在令人困惑的状态下可用,但无法完美运行。以下至少是有效的。

    从数据库上下文菜单中选择“任务>导出数据”(在表级别也不起作用) 对于源,选择“Microsoft OLE DB Provider for SQL Server” 对于目标,选择“平面文件...”,并将“格式”指定为分隔符,text qualifier 指定为双引号 选择表或查询(我使用查询) 完成向导

你应该很高兴!

【讨论】:

您会认为这会起作用,但没有 - 数据中包含双引号的列未正确转义。 Faux-csv 是所有 SQL Server 在导出向导中处理的。 我或我的消费者没有理由抱怨文本字段中的数据包含逗号和单引号。正如我已经提到的,我正在使用查询选项,如果您知道脏字段,您可以随时使用quotename 包装它们。值得庆幸的是,虽然没有遇到双引号。而且我建议使用本机选项,而不是依赖外部解决方案。 这个选项仍然是最实用的,即使它不会自动转义双引号。用 replace() 转义双引号很容易。【参考方案11】:

我的正常解决方法是将其构建到查询中:

SELECT '"' + REPLACE(CAST(column AS NVARCHAR(4000)), '"', '""') + '"' AS Header, ... FROM ...

您可以将其构建到用户定义的函数中,使其更容易一些,但您必须为每种数据类型构建一个单独的函数。

【讨论】:

可能没有必要,但我发现'"' + REPLACE(CAST(column AS VARCHAR), '"', '""') + '"' 更容易。这样我就不用担心削弱领域了。 今天,我使用 varchar(max)。当我最初写这篇文章的时候,我刚从一家商店里出来,那家商店还只有(呃)Sql Server 2000,而且才开始看 2005。 您可能还需要保留列类型,例如NVARCHAR 如果原始类型是 NVARCHAR 好点。 varchar => nvarchar 正在扩大,不会破坏东西,但 nvarchar => varchar 可能会丢失数据。 best 要做的事情是使用与原始列匹配的任何内容,但是由于人们倾向于从堆栈溢出中复制/粘贴示例代码,因此我的答案中的代码可能更适合使用 nvarchar(而这现在进行了更改)。 由于微软不能做一些像导出到 csv 文件这样基本的事情,这是最好的解决方案。我没有使用投票最多的解决方案正确导出带有换行符的文件。【参考方案12】:

我认为最简单的方法是打开 excel 并从 SQL 连接导入数据,而不是使用 SSMS 导出.... 我正在使用 SSMS 2016,它没有选项“在保存 .csv 结果时引用包含列表分隔符的字符串”大概是因为它不起作用

罗恩

【讨论】:

【参考方案13】:

在 SSMS 2012 中有一个选项,在“工具”->“选项”->“查询结果”->“SQL Server”->“结果到网格”中,它被称为“在保存 .csv 结果时引用包含列表分隔符的字符串”。我不知道这样的选择已经存在了多久,但我对两件事感到困惑:

    怎么默认没有开启 为什么它是一个选项,而不是 CSV 导出代码的固有部分

它只是违背了默认行为是无法正确导入的 CSV 导出的信念。我注意到 Excel 也是如此,我得去看看是否也有一个选项。

同时,感谢我的同事在我抱怨 CSV 导出器完全没用时向我指出了这个奇怪的功能,这是我找到的关于它的最佳链接,所以我想我'将知识放在这里以供将来的搜索者使用。

更新

截图如下:

【讨论】:

SSMS 2008 中也存在。 Note:SSMS 将限定包含分隔符或限定符的字段,但不会限定包含换行符的字段。所以在这方面 SSMS 会产生技术上无效的 CSV 文件 对于其他与我有同样问题的人:您需要打开一个新的查询编辑器窗口才能使更改生效。在更改行为之前/之后对同一结果集执行Save Results As.. 对导出的 CSV 没有影响。 在 SSMS v17 中,我发现缺少指定的选项,但它似乎已与另一个选项“复制或保存结果时包含列标题”合并,因为检查具有预期的效果为了我。设置生效仍然需要打开一个新的查询窗口。 微软:“让 CSV 成为 SSMS 的默认导出格式”。还有微软:“让我们忽略基本的实现细节。”【参考方案14】:

这些设置的不同组合可能会导致输出不正确或部分数据。这是因为微软认为解决这些问题不够重要。我只是解释将结果发送到文件时 CSV 文件会发生什么。

要获得好的结果,请执行以下操作:

打开新的查询窗口(新标签/会话)...如果不这样做,下面的配置将丢失并设置回默认值

编写查询以处理引号内的引号,并将所有字符串数据类型包装在引号中。另请注意,不同的 DBMS 和编程语言语法接受不同的转义双引号语法(如果将此输出用作另一个系统的输入)。有些人使用\"。有些人使用""。 XML 使用"。可能是微软选择忽略此功能的原因,因此他们不必处理这些参数。

..如果新系统的Escape Sequence是"".

SELECT '"' + REPLACE(CAST(column1 AS VARCHAR(MAX)), '"', '""') + '"' FROM table1

..如果新系统的Escape Sequence是\".

SELECT '"' + REPLACE(CAST(column1 AS VARCHAR(MAX)), '"', '\"') + '"' FROM table1

配置:

查询选项>结果>选中“复制或保存结果时包括列标题”

查询选项>结果>“保存.csv结果时引用包含列表分隔符的字符串” - BROKEN;不要使用!

查询选项 > 结果 > 其他未选中

查询选项>结果>文本>逗号分隔(设置在右上角)

查询选项>结果>文本>“在结果集中包含列标题”选中

查询选项>结果>文本>其他未选中

查询选项 > 结果 > 文本 > “每列中显示的最大字符数” - 设置为最大长度,这样字符串就不会被截断。

查询 > 要归档的结果(这是所有 3 个选项之间的切换)

执行查询 (F5)

报告文件名提示

打开文件查看结果

注意:如果您需要定期执行此操作,您最好 只是在.NET 或 Java 中开发一个可以为你做这件事的程序, 或任何您喜欢的语言。否则你有一个 犯错的概率很高。然后非常注意 在您定义您的系统之前,您要导入的系统的语法 导出 SQL Server。

【讨论】:

【参考方案15】:

你觉得Export to CSV from SSMS via PowerShell怎么样?这篇文章描述了如何在 SSMS 中定义一个外部工具,将当前选择的查询发送到一个导出为 CSV 的 PowerShell 脚本。

【讨论】:

到目前为止,这看起来是最划算的。我什至没有将它添加到 SSMS 的外部工具菜单中 - 我只是从命令行运行它。

以上是关于如何在 SQL Server Management Studio 中以“真实”CSV 格式获取导出输出?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 SQL Server Management Studio (2008) 在 SQL Server Compact Edition 中创建列

如何在 SQL Server Management Studio 中管理 SQL CE 数据库?

如何在 SQL Server Management Studio 中加入 3 列?

如何在 SQL Server Management Studio 中查看查询历史记录

我用sql server 2008 management studio 连接 sql server 2005, 提示4064错误,请问如何解决?

如何在 Microsoft SQL Server Management Studio 2014 中更新表