BCP实用程序SQL Server导出到CSV-永远不会创建目标CSV文件

问题描述

sql Server 2017中使用bcp实用程序时遇到以下错误

我需要使用逗号作为列定界符将数据从sql Server中的视图导出到.CSV文件中。我的数据在某些列中包含逗号。因此,在使用[+'"' column_name + '"']创建视图时,我将“用作列限定符。

我尝试了3种不同的方式:

选项1:

declare @sql varchar(8000)
select @sql = 'bcp "SELECT * FROM MyDB.dbo.MyTable
          WHERE Rn BETWEEN 1 AND 100 ORDER BY Rn"
       queryout "E:\MyFolder\MyFileName.txt" -c -t,-T -S' + @@servername 
exec master..xp_cmdshell @sql

选项2:

declare @sql varchar(8000)
select @sql = 'bcp "SELECT * FROM MyDB.dbo.MyTable
          WHERE Rn BETWEEN 1 AND 100 ORDER BY Rn"
       queryout "E:\MyFolder\MyFileName.txt" -c -t,[MyServer_Name] -T -S'
exec master..xp_cmdshell @sql

选项3

   declare @sql varchar(8000)
   select @sql = 'bcp "SELECT * FROM MyDB.dbo.MyTable
              WHERE Rn BETWEEN 1 AND 100 ORDER BY Rn"
           queryout "E:\MyFolder\MyFileName.txt" -c -t,[MyServer_Name] -T -S ' + '@@servername' 
   exec master..xp_cmdshell @sql

在每种情况下,我都得到相同的输出,但是从未创建CSV文件

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]        [-K application intent]  [-l login timeout]
  NULL

PS :我找到了另一种解决方案,可以将数据从sql Server导入到.CSV中。但是这里的问题是sqlcmd(与bcp不同)不接受两个字符作为文本限定符。我决定在逗号后使用2个字符~^的文本限定符作为字段分隔符。

 exec master..xp_cmdshell 'sqlcmd -s -W -Q "set nocount on;select * from MyTable" | findstr /v /c:"-" /b > "E:\MyFile.csv"' 

其中-s是col_separator

指定列分隔符。认值为空格。此选项设置sqlcmd脚本变量sqlCMDCOLSEP。要使用对操作系统具有特殊含义的字符,例如“与”号(&)或分号(;),请将该字符括在引号(“)中。列分隔符可以是任何8位字符。({{3 }})

解决方法

提供给xp_cmdshell的命令行不能跨越多行文本,因此需要在一行上完全指定。尝试将命令构建为一系列串联的字符串,如下所示:

declare @sql varchar(8000) =
    'bcp' +
    ' "select * from MyDB.dbo.MyTable WHERE Rn BETWEEN 1 AND 100 order by Rn"' +
    ' queryout' +
    ' "E:\MyFolder\MyFileName.txt"' +
    ' -c -t,-T -S' + @@servername 
exec master..xp_cmdshell @sql

在连接字符串时,请注意需要在每个段之间包含空格,以便命令行参数不会相互碰到。

,

P.S。

我找到了另一种解决方案,可以通过SQL Server将数据导入CSV。但是这里的问题是,与bcp不同,sqlcmd不会将字符用作文本限定符。我决定使用逗号后的2个字符〜^作为文本分隔符。

exec master..xp_cmdshell 'sqlcmd -s -W -Q "set nocount on;select * from MyTable" | findstr /v /c:"-" /b > "E:\MyFile.csv"' 

-s是col_separator的位置指定列分隔符。默认值为空格。此选项设置sqlcmd脚本变量SQLCMDCOLSEP。要使用对操作系统具有特殊含义的字符,例如“与”号(&)或分号(;),请将该字符括在引号(“)中。列分隔符可以是任何8位字符。({{3 }})

我们还有另一个包括标头的替代解决方案,但是您无法控制如何传递查询。

set BCP_EXPORT_SERVER=YourServerName
set BCP_EXPORT_DB=YourDBName
set BCP_EXPORT_TABLE=YourTableName

BCP "DECLARE @colnames VARCHAR(max);SELECT @colnames = COALESCE(@colnames + ',','') + column_name from %BCP_EXPORT_DB%.INFORMATION_SCHEMA.COLUMNS where TABLE_NAME='%BCP_EXPORT_TABLE%'; select @colnames;" queryout HeadersOnly.csv -c -t,-T -S%BCP_EXPORT_SERVER%
BCP %BCP_EXPORT_DB%.dbo.%BCP_EXPORT_TABLE% out TableDataWithoutHeaders.csv -c -t"|",-T -S%BCP_EXPORT_SERVER%

set BCP_EXPORT_SERVER=
set BCP_EXPORT_DB=
set BCP_EXPORT_TABLE=

copy /b HeadersOnly.csv+TableDataWithoutHeaders.csv TableData.csv

del HeadersOnly.csv
del TableDataWithoutHeaders.csv