我尝试使用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+'))'
从字符串转换日期和/或时间时转换失败。
我认为它与所有分隔符和数据类型有关。
答案 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))
[更新]为日期添加了带引号的字符串