【问题标题】:BCP changing header column orderBCP 更改标题列顺序
【发布时间】:2016-09-30 22:22:05
【问题描述】:

我正在尝试运行以下查询:

BCP "select * from myTable " queryout C:\Temp\myTable.csv -t, -c -T -S

表:

Process  Verb   Match
P1       V1     FALSE
P2       V2     TRUE

CSV:

Match    Process    Verb
P1       V1         FALSE
P2       V2         TRUE

出于某种原因,BCP 正在按字母顺序对标题行进行排序。

上述命令在 SQL Server 2008 R2 中运行得非常好,但由于某种原因它在 SQL Server 2012 中出现了问题……我该如何解决这个问题?

【问题讨论】:

  • 奇怪的行为!如果您尝试:bcp "select Process, Verb, Match from myTable " queryout C:\Temp\myTable.csv -t, -c -T -S 会怎样?或bcp myTable in "C:\Temp\myTable.csv" -c -T -S
  • @gofr1 :这个方法有一些问题:1-我正在使用动态列数动态创建它,2-列数可以高达 150-200,3-它曾经在sql 2008 R2中工作
  • 您是否安装了 SS2012 的最新服务包?第二:如果您编写表格脚本(来自 SSMS,右键单击表格和脚本 CREATE),列的顺序是否如您所愿?
  • 您确定您的查询和 BCP 连接到同一个数据库吗?同一个服务器?如果您通过 BCP 转储列顺序并检查它是否仍然是您所期望的呢?我一直在 SQL 2012 中通过 BCP 转储数据,说实话从来没有遇到过这个问题。
  • @TT。 - 是的,如果我右键单击并从 SSMS 中选择列,它们的顺序是正确的。

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


【解决方案1】:

也许您可以尝试创建一个查询,按照INFORMATION_SCHEMA.COLUMNS.ORDINAL_POSITION 中的顺序选择列,如下面的脚本所示:

DECLARE @target_table SYSNAME='myTable';
DECLARE @target_file VARCHAR(1024)='C:\Temp\'+@target_table+'.txt';

DECLARE @cols VARCHAR(8000)=STUFF((
    SELECT 
        ','+QUOTENAME(column_name)
    FROM 
        INFORMATION_SCHEMA.COLUMNS 
    WHERE 
        TABLE_NAME=@target_table
    ORDER BY    
        ORDINAL_POSITION
    FOR XML
        PATH(''), TYPE).value('.[1]','VARCHAR(MAX)'),
    1,1,''
);

DECLARE @bcp_cmd VARCHAR(8000)=
    'BCP ' + 
        '"SELECT '+@cols+' FROM '+QUOTENAME(@target_table)+'" '+
        'QUERYOUT "'+@target_file+'" '+
        '-t, -c -T -S ' + @@SERVERNAME + ' -d ' + DB_NAME();

--SELECT @bcp_cmd;

EXEC xp_cmdshell @bcp_cmd;

【讨论】:

    【解决方案2】:

    我自己想通了。这不是 BCP,而是 SQl 中的 Syscolumns 表导致了这种情况。

    我正在从 sys.syscolumns 读取列标题。而在 Sql 2008 R2 中,sys.syscolumns 中的 id 字段对于表的每一列都是唯一的,它在 Sql 2014 中给出相同的值。

    所以,当我分别在 Sql 2008 和 2014 中运行以下查询时

    SELECT distinct name,
              ROW_NUMBER() OVER ( ORDER BY id) AS RowNumber FROM    sys.syscolumns 
       WHERE   id = OBJECT_ID('MyDB.dbo.MyTbl')
    

    在 Sql 2008 中,它给出了按 id 排序的数据,每列都是唯一的。但是在 Sql 2014 中,由于所有列的 id 相同,因此它按字母顺序对结果进行排序。

    现在,我将查询更改为

    SELECT distinct name,
         ROW_NUMBER() OVER ( ORDER BY colid) AS RowNumber FROM sys.syscolumns
    WHERE id = OBJECT_ID('MyDB.dbo.MyTbl')
    

    【讨论】:

    • 这就是为什么包含minimal reproducible example 如此重要的原因,以便人们可以重现您的问题。您的问题不包含关于sys.syscolumns 的任何信息。如果你有,人们本可以更快地帮助你。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-06-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-11
    • 1970-01-01
    相关资源
    最近更新 更多