未能使用XML模型批量插入

时间:2017-12-15 09:39:10

标签: sql-server xml bulkinsert

我正在尝试使用BULK INSERT将大量带有元数据的二进制文件插入到SQL Server表中。我想只指定要使用的列的子集(最重要的是,PK是UniqueIdentifier,我希望SQL Server生成此字段)。所以我必须使用模型文件。

不使用模型文件(为所有列输入数据)可以正常使用此文件:

00000000-F436-49D0-B5A9-02DAB2E03F45, B, , , , JVBERio4MjEzNQ0KJSVFT0Y=, 109754, 2017-12-14 14:53:23, 2017-12-14 14:53:23, number, name

这句话:

BULK INSERT Documents
FROM 'c:\temp\testdata.txt'
WITH
(
  FIELDTERMINATOR = ',',
  ROWTERMINATOR = '\n',
  ROWS_PER_BATCH = 1000, 
  FIRSTROW = 1,
  TABLOCK
)

但是当我尝试使用模型文件时,我遇到了两个不同的问题。首先,使用指定所有列的模型文件时:

<?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="NativePrefix" PREFIX_LENGTH="1"/>
  <FIELD ID="2" xsi:type="NCharPrefix" PREFIX_LENGTH="2" MAX_LENGTH="10" COLLATION="SQL_Latin1_General_CP1_CI_AS"/>
  <FIELD ID="3" xsi:type="NCharPrefix" PREFIX_LENGTH="2" MAX_LENGTH="10" COLLATION="SQL_Latin1_General_CP1_CI_AS"/>
  <FIELD ID="4" xsi:type="NCharPrefix" PREFIX_LENGTH="2" MAX_LENGTH="50" COLLATION="SQL_Latin1_General_CP1_CI_AS"/>
  <FIELD ID="5" xsi:type="NCharPrefix" PREFIX_LENGTH="2" MAX_LENGTH="50" COLLATION="SQL_Latin1_General_CP1_CI_AS"/>
  <FIELD ID="6" xsi:type="NCharPrefix" PREFIX_LENGTH="8" COLLATION="SQL_Latin1_General_CP1_CI_AS"/>
  <FIELD ID="7" xsi:type="NativeFixed" LENGTH="4"/>
  <FIELD ID="8" xsi:type="NativeFixed" LENGTH="8"/>
  <FIELD ID="9" xsi:type="NativePrefix" PREFIX_LENGTH="1"/>
  <FIELD ID="10" xsi:type="NCharPrefix" PREFIX_LENGTH="2" MAX_LENGTH="50" COLLATION="SQL_Latin1_General_CP1_CI_AS"/>
  <FIELD ID="11" xsi:type="NCharPrefix" PREFIX_LENGTH="2" MAX_LENGTH="100" COLLATION="SQL_Latin1_General_CP1_CI_AS"/>
 </RECORD>
 <ROW>
  <COLUMN SOURCE="1" NAME="DocumentId" xsi:type="SQLUNIQUEID"/>
  <COLUMN SOURCE="2" NAME="DocumentType" xsi:type="SQLNVARCHAR"/>
  <COLUMN SOURCE="3" NAME="CompanyCode" xsi:type="SQLNVARCHAR"/>
  <COLUMN SOURCE="4" NAME="CustomerNumber" xsi:type="SQLNVARCHAR"/>
  <COLUMN SOURCE="5" NAME="OrderNumber" xsi:type="SQLNVARCHAR"/>
  <COLUMN SOURCE="6" NAME="Data" xsi:type="SQLNVARCHAR"/>
  <COLUMN SOURCE="7" NAME="Size" xsi:type="SQLINT"/>
  <COLUMN SOURCE="8" NAME="Created" xsi:type="SQLDATETIME"/>
  <COLUMN SOURCE="9" NAME="Modified" xsi:type="SQLDATETIME"/>
  <COLUMN SOURCE="10" NAME="InvoiceNumber" xsi:type="SQLNVARCHAR"/>
  <COLUMN SOURCE="11" NAME="Title" xsi:type="SQLNVARCHAR"/>
 </ROW>
</BCPFORMAT>

和本声明:

BULK INSERT Documents   
   FROM 'c:\Temp\testiness.txt'   
   WITH
   (
      FIELDTERMINATOR = ',',
      ROWTERMINATOR = '\n',
      ROWS_PER_BATCH = 1000, 
      FIRSTROW = 1,
      TABLOCK,
      FORMATFILE = 'c:\Temp\modeltest.xml'
   );  
GO 

我收到此错误:

  

Msg 4866,Level 16,State 7,Line 1
  批量加载失败。第1行第2列的数据文件中的列太长。验证是否正确指定了字段终止符和行终止符。

     

Msg 7399,Level 16,State 1,Line 1
  链接服务器“(null)”的OLE DB提供程序“BULK”报告错误。提供商没有提供有关错误的任何信息。

     

Msg 7330,Level 16,State 2,Line 1
  无法从OLE DB提供程序“BULK”获取链接服务器“(null)”。“

使用此简化模型文件(以及值较少的文本文件)时:

<?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="NCharPrefix" PREFIX_LENGTH="2" MAX_LENGTH="10" COLLATION="SQL_Latin1_General_CP1_CI_AS"/>
  <FIELD ID="2" xsi:type="NCharPrefix" PREFIX_LENGTH="2" MAX_LENGTH="10" COLLATION="SQL_Latin1_General_CP1_CI_AS"/>
  <FIELD ID="3" xsi:type="NCharPrefix" PREFIX_LENGTH="2" MAX_LENGTH="50" COLLATION="SQL_Latin1_General_CP1_CI_AS"/>
  <FIELD ID="4" xsi:type="NCharPrefix" PREFIX_LENGTH="2" MAX_LENGTH="50" COLLATION="SQL_Latin1_General_CP1_CI_AS"/>
  <FIELD ID="5" xsi:type="NCharPrefix" PREFIX_LENGTH="8" COLLATION="SQL_Latin1_General_CP1_CI_AS"/>
  <FIELD ID="6" xsi:type="NativeFixed" LENGTH="4"/>
  <FIELD ID="7" xsi:type="NativeFixed" LENGTH="8"/>
  <FIELD ID="8" xsi:type="NativePrefix" PREFIX_LENGTH="1"/>
  <FIELD ID="9" xsi:type="NCharPrefix" PREFIX_LENGTH="2" MAX_LENGTH="100" COLLATION="SQL_Latin1_General_CP1_CI_AS"/>
 </RECORD>
 <ROW>
  <COLUMN SOURCE="1" NAME="DocumentType" xsi:type="SQLNVARCHAR"/>
  <COLUMN SOURCE="2" NAME="CompanyCode" xsi:type="SQLNVARCHAR"/>
  <COLUMN SOURCE="3" NAME="CustomerNumber" xsi:type="SQLNVARCHAR"/>
  <COLUMN SOURCE="4" NAME="OrderNumber" xsi:type="SQLNVARCHAR"/>
  <COLUMN SOURCE="5" NAME="Data" xsi:type="SQLNVARCHAR"/>
  <COLUMN SOURCE="6" NAME="Size" xsi:type="SQLINT"/>
  <COLUMN SOURCE="7" NAME="Created" xsi:type="SQLDATETIME"/>
  <COLUMN SOURCE="8" NAME="Modified" xsi:type="SQLDATETIME"/>
  <COLUMN SOURCE="9" NAME="Title" xsi:type="SQLNVARCHAR"/>
 </ROW>
</BCPFORMAT>

我明白了:

  

Msg 257,Level 16,State 3,Line 1
  不允许从数据类型datetime到int的隐式转换。使用CONVERT函数运行此查询。

1 个答案:

答案 0 :(得分:0)

我建议将此数据导入到容错的临时表中并从那里继续。只有一个观察:

<FIELD ID="7" xsi:type="NativeFixed" LENGTH="8"/>
<FIELD ID="8" xsi:type="NativePrefix" PREFIX_LENGTH="1"/>
<FIELD ID="9" xsi:type="NCharPrefix" PREFIX_LENGTH="2" MAX_LENGTH="100"> 

对应

<COLUMN SOURCE="7" NAME="Size" xsi:type="SQLINT"/>
<COLUMN SOURCE="8" NAME="Created" xsi:type="SQLDATETIME"/>
<COLUMN SOURCE="9" NAME="Modified" xsi:type="SQLDATETIME"/>

Nr 7似乎是INT(尽管有8个字节),而8和9指向日期值(按列的名称和类型),而<FIELD>定义不是是一致的。