【问题标题】:BCP utility SQL Server Export to CSV - destination CSV file never gets createdBCP 实用程序 SQL Server 导出到 CSV - 永远不会创建目标 CSV 文件
【发布时间】:2020-10-13 23:33:38
【问题描述】:

在 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 位字符。(https://docs.microsoft.com/en-us/sql/tools/sqlcmd-utility?view=sql-server-ver15 )

【问题讨论】:

  • 为什么需要使用逗号作为分隔符?这是最糟糕的分隔符。无论如何,如果这是你得到的输出(BCP 帮助),那么看起来 BCP 命令没有正确构建
  • 问题中的代码格式是否代表 SQL Server 中的实际代码格式?如果是这种情况 - 您不能像这样将命令行拆分为多行。 bcp "select * from MyDB.dbo.MyTable 不是有效命令。
  • 如果您使用它在 SQL Server 之间传输数据,请忘记分隔符。使用原生格式-ndocs.microsoft.com/en-us/sql/relational-databases/import-export/…

标签: sql-server csv export-to-csv bcp


【解决方案1】:

提供给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

连接字符串时,请注意每个段之间需要包含空格的位置,以免命令行参数相互冲突。

【讨论】:

  • 从 SLQ 服务器读取时,我需要指定什么参数以允许 bcp 在平面文件中包含标头?
  • 我找到了替代解决方案 exec master..xp_cmdshell 'sqlcmd -s -W -Q "set nocount on;select * from MyTable" | findstr /v /c:"-" /b > "E:\MyFile.csv"' 问题是 sqlcmd 与 bcp 不同,除了将字符作为文本限定符之外。我决定在逗号后面使用 2 个字符 ~^ 的文本限定符作为文件分隔符。
【解决方案2】:

附言

我找到了从 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 位字符。(https://docs.microsoft.com/en-us/sql/tools/sqlcmd-utility?view=sql-server-ver15 )

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

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
 

【讨论】:

猜你喜欢
  • 1970-01-01
  • 2020-05-07
  • 2021-11-13
  • 2015-11-28
  • 1970-01-01
  • 2012-03-25
  • 1970-01-01
  • 1970-01-01
  • 2013-01-06
相关资源
最近更新 更多