【问题标题】:bcp: replacing a value in the data field with null for a columnbcp:将列的数据字段中的值替换为 null
【发布时间】:2015-07-06 21:49:02
【问题描述】:

假设我有一张桌子

CREATE TABLE [T1](
   [ID] [int] NOT NULL,
   [Level] [int] NULL,
   [N1] [int] NULL,
   [N2] [int] NULL)

我有一个包含四个分隔字段的文件

 1,2,3,4
 2,a,5,8
 3,X,11,12
 ...

文件很大(几千万或几亿行) 我正在使用 bcp 实用程序导入它。显然,第二个字段不是整数,但对我的应用程序来说并不重要。所以我想将它导入到这个表中,跳过第二个字段。我无法更改文件格式或数据库架构。我有以下bcp格式文件

<?xml version="1.0"?>
<BCPFORMAT xmlns="http://schemas.microsoft.com/sqlserver/2004/bulkload/format" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
 <RECORD>
  <FIELD ID="1" xsi:type="CharTerm" TERMINATOR="\t"/>
  <FIELD ID="2" xsi:type="CharTerm" TERMINATOR="\t"/>
  <FIELD ID="3" xsi:type="CharTerm" TERMINATOR="\t"/>
  <FIELD ID="4" xsi:type="CharTerm" TERMINATOR="\n"/>
 </RECORD>
 <ROW>
  <COLUMN SOURCE="1" NAME="ID" xsi:type="SQLINT"/>
  <COLUMN SOURCE="2" NAME="Level" xsi:type="SQLINT"/>
  <COLUMN SOURCE="3" NAME="N1" xsi:type="SQLINT"/>
  <COLUMN SOURCE="4" NAME="N2" xsi:type="SQLINT"/>
 </ROW>
</BCPFORMAT>

问题是:如何指定字段 2 而不是字段 2,而我希望列 2 为 NULL?换句话说,我如何指示 bcp 跳过一列?如果我只是删除

<COLUMN SOURCE="2" ...

所有列都将移动,第 2 列填充字段 3 中的数据,第 3 列填充字段 4 中的值,第 4 列留空。 另一种方法是将此列设置为某个固定值,例如,为每一行设置 0。

【问题讨论】:

    标签: sql-server bulkinsert bcp


    【解决方案1】:

    因此,根据文档:如果您想跳过除最后一列之外的任何列,您需要创建一个视图来公开您希望导入的列的子集。

    视图应该看起来像create view v1 as select id, n1, n2 from t1,然后您可以从格式文件中删除&lt;COLUMN SOURCE="2" NAME="Level" xsi:type="SQLINT"/&gt;,并使用视图作为目标进行导入。

    如果您想为缺少的列设置默认值,您应该在导入之前为该列添加默认约束。

    有关参考,请参阅: Using a Format File to Skip a Table ColumnUsing a Format File to Skip a Data Field

    【讨论】:

    • 谢谢!我怎么没想到通过视图插入技巧? :)
    【解决方案2】:

    除了@jpw 的回复,你能试试OPENROWSET 吗?这是来自 BOL 的示例 - Use a Format File to Map Table Columns to Data-File Fields。只需将任何列替换为 NULL。老实说,我不知道这是否可行,但试一试:)

    USE AdventureWorks2012;
    GO
    INSERT INTO myTestOrder 
      SELECT Col1, Col2, Col3, Col4
          FROM  OPENROWSET(BULK  'C:\myTestOrder-c.txt',
          FORMATFILE='C:\myTestOrder.Xml'  
           ) AS t1;
    GO
    

    【讨论】:

    • 我试过了,它确实有效,除了列需要匹配格式文件中的列。即使 MSDN 文档指出:如果您必须跳过除最后一列之外的任何内容,您必须创建一个仅包含数据文件中包含的列的目标表视图,但似乎不需要该视图。
    • 澄清一下,如果我使用 INSERT INTO t1 (id, n1, n2) select * from openrowset... 并且在从格式文件中删除源列之后,它会起作用。
    猜你喜欢
    • 2018-08-22
    • 1970-01-01
    • 1970-01-01
    • 2015-01-31
    • 1970-01-01
    • 2021-04-04
    • 2017-10-22
    • 2017-08-16
    • 1970-01-01
    相关资源
    最近更新 更多