bcp:将数据字段中的值替换为列的空值

bcp: replacing a value in the data field with null for a column

假设我有一个 table

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 实用程序导入它。显然,第二个字段不是整数,但对于我的应用程序来说并不重要。所以我想将它导入到这个 table,跳过第二个字段。我无法更改文件格式或数据库架构。我有以下 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 列仅为 NULL 而不是字段 2?换句话说,我如何指示 bcp 跳过一列?如果我只是删除

<COLUMN SOURCE="2" ...

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

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

视图应类似于 create view v1 as select id, n1, n2 from t1,然后您可以从格式文件中删除 <COLUMN SOURCE="2" NAME="Level" xsi:type="SQLINT"/>,并使用视图作为目标进行导入。

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

有关参考资料,请参阅: Using a Format File to Skip a Table Column and Using a Format File to Skip a Data Field

除了@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