我尝试运行存储过程查询以使用 bcp 作为 SQL Server 上的日常任务导出到 CSV 文件
例如,使用普通查询就可以正常工作
select @csv = 'bcp "select * from Table" queryout '+@FileAndPath2+' -c -t, -T -S' +@@servername
但是,当我添加查询(即日期范围内的交易数据列表)时,它似乎崩溃了
@p_companyId uniqueidentifier = '189be460-99d1-42e9-b4ed-8de6f8724ce8',
@p_Path varchar(300) = 'C:\temp\','
@p_Date datetime = getutcdate
set @FileAndPath2=@p_Path + CONVERT(nvarchar(30), @p_Date, 112) + '_' + CONVERT(varchar(36), @p_companyId) + '_transactionslog.csv';
declare @csv varchar(8000)
declare @csvSQL varchar(8000)
set @csvSQL = 'SELECT TOP (100) [KICSDEV].dbo.MOVIEDETAIL.Title , [KICSDEV].dbo.MEMBERMOVIEPURCHASELOG.MemberId, [KICSDEV].dbo.MEMBERMOVIEPURCHASELOG.CreateDateTime as ''DateTime'' FROM [KICSDEV].dbo.MEMBERMOVIEPURCHASELOG INNER JOIN [KICSDEV].dbo.MOVIEDETAIL ON [KICSDEV].dbo.MEMBERMOVIEPURCHASELOG.MovieDetailId = [KICSDEV].dbo.MOVIEDETAIL.MovieDetailId INNER JOIN [KICSDEV].dbo.MEMBER ON [KICSDEV].dbo.MEMBERMOVIEPURCHASELOG.MemberId = [KICSDEV].dbo.MEMBER.MemberId INNER JOIN [KICSDEV].dbo.CINEMA ON [KICSDEV].dbo.MEMBER.CinemaId = [KICSDEV].dbo.CINEMA.CinemaId WHERE ([KICSDEV].dbo.CINEMA.CompanyId = '+ @p_companyId + ' and [KICSDEV].dbo.MEMBERMOVIEPURCHASELOG.CreateDateTime >= ' + @p_Date +' and [KICSDEV].dbo.MEMBERMOVIEPURCHASELOG.CreateDateTime < DATEADD (day , 1 , '+@p_Date+'))'
select @csvSQL
select @csv = 'bcp "'+ @csvSQL +'" queryout '+@FileAndPath2+' -c -t, -T -S' +@@servername
exec master..xp_cmdshell @csv
当我运行时,它显示为“数据类型 varchar 和 uniqueidentifier 在添加运算符中不兼容”。错误
当我将 Company 更改为字符串而不是查询中的变量时,它工作正常,但出现错误。
set @csvSQL = 'SELECT TOP (100) [KICSDEV].dbo.MOVIEDETAIL.Title , [KICSDEV].dbo.MEMBERMOVIEPURCHASELOG.MemberId, [KICSDEV].dbo.MEMBERMOVIEPURCHASELOG.CreateDateTime as ''DateTime'' FROM [KICSDEV].dbo.MEMBERMOVIEPURCHASELOG INNER JOIN [KICSDEV].dbo.MOVIEDETAIL ON [KICSDEV].dbo.MEMBERMOVIEPURCHASELOG.MovieDetailId = [KICSDEV].dbo.MOVIEDETAIL.MovieDetailId INNER JOIN [KICSDEV].dbo.MEMBER ON [KICSDEV].dbo.MEMBERMOVIEPURCHASELOG.MemberId = [KICSDEV].dbo.MEMBER.MemberId INNER JOIN [KICSDEV].dbo.CINEMA ON [KICSDEV].dbo.MEMBER.CinemaId = [KICSDEV].dbo.CINEMA.CinemaId WHERE ([KICSDEV].dbo.CINEMA.CompanyId = ''189be460-99d1-42e9-b4ed-8de6f8724ce8'' and [KICSDEV].dbo.MEMBERMOVIEPURCHASELOG.CreateDateTime >= ' + @p_Date +' and [KICSDEV].dbo.MEMBERMOVIEPURCHASELOG.CreateDateTime < DATEADD (day , 1 , '+@p_Date+'))'
从字符串转换日期和/或时间时转换失败。
我认为这与所有分隔符和数据类型有关。
最佳答案
这里有几个问题。这样想问题。您正在为命令行实用程序构建命令行参数,因此所有内容都必须构建到字符串中。
第 1 步:在连接查询之前确保所有内容都是字符串
您缺少一些 Actor Cast(@p_companyId as VarChar(36))
和CAST( @p_Date as VarChar(25))
您还需要在格式化字符串中引用公司 ID 和日期的转换。我建议创建一个新变量,将 UTC 日期作为字符串 @p_DateAsStr varchar(25) = CAST( @p_Date as VarChar(25) )
,而不是一遍又一遍地重复。
第 2 步:查询中的字符串值需要加引号
由于您正在调用 BCP,因此必须将查询格式化为字符串,因此需要用引号引起来的字符串参数。您必须使用单引号,因为 BCP 的字符串位于双引号中,例如:
set @csvSQL = 'SELECT .... WHERE CompanyId = '''+ Cast(@p_companyId as VarChar(36)) + ''....'
第 3 步:根据内置函数的需要将查询中的任何字符串转换回 native 类型
我们可以将 GUID 指定为字符串(如果我们引用它),但对于 DataAdd
我们需要像这样从字符串转换回日期
CreateDateTime < DATEADD (day , 1 , CAST(''' +@p_DateAsStr+''' as DateTime))
[更新]为日期添加了带引号的字符串
关于mysql - BCP SQL 导出到 CSV,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32368827/