当前位置:  开发笔记 > 后端 > 正文

如何使用sqlcmd从SQL Server导出数据为CSV格式?

如何解决《如何使用sqlcmd从SQLServer导出数据为CSV格式?》经验,为你挑选了5个好方法。

我可以很容易地将数据转储到文本文件中,例如:

sqlcmd -S myServer -d myDB -E -Q "select col1, col2, col3 from SomeTable" 
     -o "MyData.txt"

但是,我查看了帮助文件,SQLCMD但没有看到专门针对CSV的选项.

有没有办法使用表格将数据从表格转储到CSV文本文件SQLCMD



1> scottm..:

你可以运行这样的东西:

sqlcmd -S MyServer -d myDB -E -Q "select col1, col2, col3 from SomeTable" 
       -o "MyData.csv" -h-1 -s"," -w 700

-h-1 从结果中删除列名称标题

-s"," 将列分隔符设置为,

-w 700 将行宽设置为700个字符(这需要与最长的行一样宽,否则它将换行到下一行)


这样做的警告是您的数据可能不包含任何逗号.
@JIsaak然后确保您的数据没有任何双引号或确保用双引号替换双引号.
这个答案现在已经过时了.PowerShell脚本更灵活,可以作为作业代理在SQL Server中运行.

2> ESV..:
sqlcmd -S myServer -d myDB -E -o "MyData.txt" ^
    -Q "select bar from foo" ^
    -W -w 999 -s","

最后一行包含特定于CSV的选项.

-W   从每个单独的字段中删除尾随空格

-s","   将列分隔符设置为逗号(,)

-w 999   将行宽设置为999个字符

scottm的答案与我使用的非常接近,但我觉得这-W是一个非常好的补充:当我在其他地方使用CSV时,我不需要修剪空格.

另请参阅MSDN sqlcmd参考.它使/?选项的输出变得羞耻.


@sims在query/inputfile的开头"设置nocount on"
如何删除标题上的下划线?
这就像一个魅力,但如果你的列包含分隔符我得到一个损坏的csv文件...

3> Iain Samuel ..:

使用PowerShell,您可以通过将Invoke-Sqlcmd管道传输到Export-Csv来巧妙地解决问题.

#Requires -Module SqlServer
Invoke-Sqlcmd -Query "SELECT * FROM DimDate;" `
              -Database AdventureWorksDW2012 `
              -Server localhost |
Export-Csv -NoTypeInformation `
           -Path "DimDate.csv" `
           -Encoding UTF8

SQL Server 2016包含SqlServer模块,其中包含Invoke-Sqlcmdcmdlet,即使您刚刚安装SSMS 2016,它也将拥有该模块.在此之前,SQL Server 2012包含旧的SQLPS模块,该模块将当前目录更改SQLSERVER:\为模块为首先使用(以及其他错误)因此,您需要将#Requires上面的行更改为:

Push-Location $PWD
Import-Module -Name SQLPS
# dummy query to catch initial surprise directory change
Invoke-Sqlcmd -Query "SELECT 1" `
              -Database  AdventureWorksDW2012 `
              -Server localhost |Out-Null
Pop-Location
# actual Invoke-Sqlcmd |Export-Csv pipeline

若要使SQL Server 2008和2008 R2的示例适应,请#Requires完全删除该行,并使用sqlps.exe实用程序而不是标准PowerShell主机.

Invoke-Sqlcmd是与sqlcmd.exe等效的PowerShell.而不是文本它输出System.Data.DataRow对象.

-Query参数的作用类似于-Qsqlcmd.exe 的参数.传递一个描述要导出的数据的SQL查询.

-Database参数的作用类似于-dsqlcmd.exe 的参数.传递包含要导出的数据的数据库的名称.

-Server参数的作用类似于-Ssqlcmd.exe 的参数.将它传递给包含要导出的数据的服务器的名称.

Export-CSV是一个PowerShell cmdlet,它将通用对象序列化为CSV.它附带PowerShell.

-NoTypeInformation参数抑制了不属于CSV格式的额外输出.默认情况下,cmdlet会写入包含类型信息的标头.它可以让您在以后反序列化时知道对象的类型Import-Csv,但它会混淆期望标准CSV的工具.

-Path参数的作用类似于-osqlcmd.exe 的参数.如果您使用旧的SQLPS模块,则此值的完整路径是最安全的.

-Encoding参数的工作方式类似于-f-usqlcmd.exe的参数.默认情况下,Export-Csv仅输出ASCII字符,并用问号替换所有其他字符.使用UTF8代替保留所有字符并与大多数其他工具保持兼容.

此解决方案优于sqlcmd.exe或bcp.exe的主要优点是您不必破解命令输出有效的CSV.Export-Csv cmdlet可以为您处理所有内容.

主要缺点是Invoke-Sqlcmd在沿管道传递之前读取整个结果集.确保您有足够的内存用于要导出的整个结果集.

数十亿行可能无法顺利运行.如果这是一个问题,您可以尝试其他工具,或Invoke-Sqlcmd使用 System.Data.SqlClient.SqlDataReader类滚动自己的高效版本.


老实说其他答案很糟糕,这是正确做到的唯一方法.我希望它更明显.
这是一个比被接受的答案好得多的答案.

4> johndacostaa..:

这不是bcp意味着什么?

bcp "select col1, col2, col3 from database.schema.SomeTable" queryout  "c:\MyData.txt"  -c -t"," -r"\n" -S ServerName -T

从命令行运行此命令以检查语法.

bcp /?

例如:

usage: bcp {dbtable | query} {in | out | queryout | format} datafile
  [-m maxerrors]            [-f formatfile]          [-e errfile]
  [-F firstrow]             [-L lastrow]             [-b batchsize]
  [-n native type]          [-c character type]      [-w wide character type]
  [-N keep non-text native] [-V file format version] [-q quoted identifier]
  [-C code page specifier]  [-t field terminator]    [-r row terminator]
  [-i inputfile]            [-o outfile]             [-a packetsize]
  [-S server name]          [-U username]            [-P password]
  [-T trusted connection]   [-v version]             [-R regional enable]
  [-k keep null values]     [-E keep identity values]
  [-h "load hints"]         [-x generate xml format file]
  [-d database name]

请注意,bcp无法输出列标题.

请参阅:bcp Utility文档页面.

上面的例子:

bcp.exe MyTable out "D:\data.csv" -T -c -C 65001 -t , ...


如果您还需要将列名称导出为标题,该怎么办?是否有使用bcp的直接通用解决方案?

5> Rudism..:

对于任何想要执行此操作但也有列标题的人的注释,这是我使用批处理文件的解决方案:

sqlcmd -S servername -U username -P password -d database -Q "set nocount on; set ansi_warnings off; sql query here;" -o output.tmp -s "," -W
type output.tmp | findstr /V \-\,\- > output.csv
del output.tmp

这会将初始结果(包括标题和数据之间的----,----分隔符)输出到临时文件中,然后通过findstr过滤掉该行.请注意,它不是完美的,因为它过滤掉-,-- 如果输出中只有一列,它将无效,并且它还会过滤掉包含该字符串的合法行.


总是在双引号内加上^的正则表达式,或者你得到奇怪的结果,因为^是cmd.exe的转义字符.就我所知,上面的两个正则表达式都不能正常工作,但这样做:findstr/r/v"^ - [ - ,]* - .$"(在测试时似乎需要$之前的. echo,但可能不适用于sqlcmd输出)
推荐阅读
U友50081205_653
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有