BCP 实用程序 SQL 服务器导出到 CSV - 永远不会创建目标 CSV 文件
BCP utility SQL Server Export to CSV - destination CSV file never gets created
我在 SQL Server 2017 中使用 bcp
实用程序时遇到以下错误。
我需要使用逗号作为列分隔符将数据从 SQL 服务器中的视图导出到 .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 服务器导入 .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"'
where -s
is col_separator
Specifies the column-separator character. The default is a blank space. This option sets the sqlcmd scripting variable SQLCMDCOLSEP. To use characters that have special meaning to the operating system such as the ampersand (&), or semicolon (;), enclose the character in quotation marks ("). The column separator can be any 8-bit character.( https://docs.microsoft.com/en-us/sql/tools/sqlcmd-utility?view=sql-server-ver15 )
提供给 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
连接字符串时请注意需要在每个段之间包含白色 space 的位置,这样命令行参数就不会 运行 相互混淆。
P.S.
我找到了从 SQL 服务器将数据导入 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 指定 column-separator 字符。默认值为空白 space。此选项设置 sqlcmd 脚本变量 SQLCMDCOLSEP。要使用对操作系统有特殊意义的字符,例如和号 (&) 或分号 (;),请将字符括在引号 (") 中。列分隔符可以是任何 8 位字符。( https://docs.microsoft.com/en-us/sql/tools/sqlcmd-utility?view=sql-server-ver15 )
我们还有另一种替代解决方案,其中包括 headers,但您无法控制如何传递查询。
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
我在 SQL Server 2017 中使用 bcp
实用程序时遇到以下错误。
我需要使用逗号作为列分隔符将数据从 SQL 服务器中的视图导出到 .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 服务器导入 .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"'
where
-s
is col_separatorSpecifies the column-separator character. The default is a blank space. This option sets the sqlcmd scripting variable SQLCMDCOLSEP. To use characters that have special meaning to the operating system such as the ampersand (&), or semicolon (;), enclose the character in quotation marks ("). The column separator can be any 8-bit character.( https://docs.microsoft.com/en-us/sql/tools/sqlcmd-utility?view=sql-server-ver15 )
提供给 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
连接字符串时请注意需要在每个段之间包含白色 space 的位置,这样命令行参数就不会 运行 相互混淆。
P.S.
我找到了从 SQL 服务器将数据导入 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 指定 column-separator 字符。默认值为空白 space。此选项设置 sqlcmd 脚本变量 SQLCMDCOLSEP。要使用对操作系统有特殊意义的字符,例如和号 (&) 或分号 (;),请将字符括在引号 (") 中。列分隔符可以是任何 8 位字符。( https://docs.microsoft.com/en-us/sql/tools/sqlcmd-utility?view=sql-server-ver15 )
我们还有另一种替代解决方案,其中包括 headers,但您无法控制如何传递查询。
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