BCP SQL导出为CSV

时间:2015-09-03 06:53:18

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

我尝试使用bcp作为SQL服务器上的日常任务运行Store过程查询以导出到CSV文件

使用普通查询可以正常工作,例如

  

选择@csv =' bcp"从表格中选择*" queryout' + @ FileAndPath2 +' -c -t,-T-S' + @@服务器名

然而,当我添加我的查询时,这是一个日期范围内的交易数据列表,似乎崩溃了

@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

当我运行它时出现&#34;数据类型varchar和uniqueidentifier在add运算符中是不兼容的。&#34;错误

当我将公司更改为字符串而不是查询中的变量时,它可以正常工作但是错误。

    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 个答案:

答案 0 :(得分:1)

这里有几个问题。以这种方式思考问题。您正在为命令行实用程序构建命令行参数,因此必须将所有内容构建到字符串中。

第1步:在连接查询之前确保所有内容都是字符串

您缺少某些演员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步:根据内置函数的需要,将查询中的任何字符串转换回本机类型

我们可以将GUID指定为字符串(如果我们引用它),但对于DataAdd我们需要从字符串转换回日期这样

CreateDateTime < DATEADD (day , 1 , CAST(''' +@p_DateAsStr+''' as DateTime))

[更新]为日期添加了带引号的字符串