【问题标题】:Single quote issue while creating the query for BCP utility为 BCP 实用程序创建查询时出现单引号问题
【发布时间】:2019-07-04 11:07:43
【问题描述】:

我陷入了 bcp 查询字符串格式问题。我在某处遗漏了一个报价,无法找到它。这是我的代码:

BEGIN
DECLARE @stmt_c varchar(1000);
DECLARE @Current_Database varchar(1000) = (SELECT DB_NAME());
DECLARE @YYYYMMDD varchar(1000) = (SELECT convert(varchar, GETDATE(), 112));
DECLARE @YYYYMMDDhhmmss varchar(1000) = (SELECT format(getdate(),'yyyyMMddHHmmss'));
DECLARE @location varchar(1000) = 'D:\BackUp 2\Data\';
DECLARE @filename varchar(1000) = 'TGF_'+@YYYYMMDDhhmmss+'_'+@YYYYMMDD+'_'+'TT.dat';
DECLARE @absPath varchar(1000) = @location+@filename;
DECLARE @recordCount varchar(1000) = (SELECT COUNT(1) FROM data_v);
DECLARE @totalBytes varchar(1000) = (SELECT ISNULL(SUM(LEN(result)),0) FROM data_v);
DECLARE @totalItems varchar(1000) = (SELECT COUNT(DISTINCT ITEM_ID) FROM ITEM_TX);
DECLARE @totalChgd varchar(1000) = '0.00000';
DECLARE @trailer varchar(1000) = 'SELECT ''TRAILER''+''|''+@recordCount+''|''+@totalBytes+''|''+@totalChgd+''|''+@totalItems';

SET @stmt_c=
    'BCP '+
     '"SELECT ''HEADER|AA|'+@YYYYMMDDhhmmss+'|'+@YYYYMMDD+'|1.0'' UNION ALL SELECT * FROM data_v UNION ALL '+ @trailer" '+
    'QUERYOUT "'+@absPath+'" '+
    '-c -t, -T -d ' + @Current_Database;
EXEC master.sys.xp_cmdshell @stmt_c;

END 

上面的代码给了我以下错误:

Incorrect syntax near ' '+
    'QUERYOUT '.
Msg 105, Level 15, State 1, Line 18
Unclosed quotation mark after the character string ' '+
    '-c -t, -T -d ' + @Current_Database;
EXEC master.sys.xp_cmdshell @stmt_c;

END 
'.

我要导出以下查询的结果集:

SELECT 'HEADER|AA|'+@YYYYMMDDhhmmss+'|'+@YYYYMMDD+'|1.0' UNION ALL SELECT * FROM data_v UNION ALL SELECT 'TRAILER|'+@recordCount+'|'+@totalBytes+'|'+@totalChgdPrem+'|'+@totalPolicies

我无法在我的代码中附加预告片查询。

【问题讨论】:

  • 所以你得到一个错误?或者是什么问题?
  • 似乎您需要正确引用您的价值观。如果它们的长度不超过 128 个字符,QUOTENAME 将在这里为您提供帮助。如果没有,您可以使用REPLACE 将单引号“加倍”。
  • 我已经用错误消息更新了我的问题。
  • 做一个PRINT @stmt_c 并检查
  • 控件不会到达 PRINT 语句。程序在 SET @stmt_c 行中失败

标签: sql-server bcp


【解决方案1】:

我解决了这个问题。

评论了@trailer 变量。

-- DECLARE @trailer varchar(1000) = 'SELECT ''TRAILER''+''|''+@recordCount+''|''+@totalBytes+''|''+@totalChgd+''|''+@totalItems';

将查询字符串修改为:

'"SELECT ''HEADER|AA|'+@YYYYMMDDhhmmss+'|'+@YYYYMMDD+'|1.0'' UNION ALL SELECT * FROM data_v UNION ALL SELECT ''TRAILER|'+@recordCount+'|'+@totalBytes+'|'+@totalChgd+'|'+@totalItems+'''" '

【讨论】:

    【解决方案2】:

    我现在可以打印出字符串了。 我已经编辑了您从表“data_v”(我无权访问)中获取数据的语句,以便它可以在我的最后工作。最后,它应该可以使用原始代码。

    现在它也会执行其他语句。

    请试试这个:

        BEGIN
    DECLARE @stmt_c varchar(1000);
    DECLARE @Current_Database varchar(1000) = (SELECT DB_NAME());
    DECLARE @YYYYMMDD varchar(1000) = (SELECT convert(varchar, GETDATE(), 112));
    DECLARE @YYYYMMDDhhmmss varchar(1000) = (SELECT format(getdate(),'yyyyMMddHHmmss'));
    DECLARE @location varchar(1000) = 'D:\BackUp 2\Data\';
    DECLARE @filename varchar(1000) = 'TGF_'+@YYYYMMDDhhmmss+'_'+@YYYYMMDD+'_'+'TT.dat';
    DECLARE @absPath varchar(1000) = @location+@filename;
    DECLARE @recordCount varchar(1000) = (SELECT '369' as col);
    DECLARE @totalBytes varchar(1000) = (SELECT '674' as col);
    DECLARE @totalItems varchar(1000) = (SELECT '14' as col);
    DECLARE @totalChgd varchar(1000) = '0.00000';
    DECLARE @trailer varchar(1000) = 'SELECT ''TRAILER|'+@recordCount+'|'+@totalBytes+'|'+@totalChgd+'|'+@totalItems;
    
    SET @stmt_c=
        'BCP '+
            '"SELECT ''HEADER|AA|'+@YYYYMMDDhhmmss+'|'+@YYYYMMDD+'|1.0'' UNION ALL SELECT * FROM data_v UNION ALL '+ @trailer+'" '+
        'QUERYOUT "'+@absPath+'" '+
        '-c -t, -T -d ' + @Current_Database;
    print @stmt_c
    
    --EXEC master.sys.xp_cmdshell @stmt_c;
    
    END 
    

    这是我最后的结果:

    BCP "SELECT 'HEADER|AA|20190705154946|20190705|1.0' UNION ALL SELECT * FROM data_v UNION ALL SELECT 'TRAILER|369|674|0.00000|14" QUERYOUT "D:\BackUp 2\Data\TGF_20190705154946_20190705_TT.dat" -c -t, -T -d master
    

    编辑: 正如你所提到的,你已经解决了这个问题,用你的解决方案来增强这个问题会更好,或者如果你不想,请删除整个问题。

    【讨论】:

    • 此输出未将变量替换为预告片中的值。正确的输出是:BCP "SELECT 'HEADER|AA|20190704174650|20190704|1.0' UNION ALL SELECT * FROM data_V UNION ALL SELECT '|TRAILER|369|674|0.00000|14'"
    • 但也许只是因为我无法访问您的数据库。要在我最后运行脚本,我必须注释所需的部分,因此它们不符合预期。您现在是否尝试过运行代码?
    • 变量仍然没有被它们的值替换。但是,我解决了这个问题。感谢马特的帮助。
    猜你喜欢
    • 2021-03-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-01
    • 2016-01-04
    • 1970-01-01
    • 2013-05-17
    相关资源
    最近更新 更多