为什么在 SQL Server 批量插入期间格式化文件会导致错误?

Dav*_*mpf 3 sql-server bulkinsert

我正在尝试使用 XML 格式文件将 CSV 文件批量插入 SQL Server 2017:

<?xml version="1.0"?>
<BCPFORMAT xmlns="https://schemas.microsoft.com/sqlserver/2004/bulkload/format" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <RECORD>
        <FIELD ID="Col_0" xsi:type="CharTerm" MAX_LENGTH="100" TERMINATOR=","/>
        <FIELD ID="Col_1" xsi:type="CharTerm" MAX_LENGTH="100" TERMINATOR=","/>
        <FIELD ID="Col_2" xsi:type="CharTerm" MAX_LENGTH="3" TERMINATOR=","/>
        <FIELD ID="Col_3" xsi:type="CharFixed" Length="19" TERMINATOR=","/>
        <FIELD ID="Col_4" xsi:type="CharFixed" Length="19" TERMINATOR=","/>
        <FIELD ID="Col_5" xsi:type="CharFixed" Length="53" TERMINATOR=","/>
        <FIELD ID="Col_6" xsi:type="CharFixed" Length="10" TERMINATOR=","/>
    </RECORD>
    <ROW>
        <COLUMN SOURCE="Col_0" NAME="NAME" xsi:type="SQLVARCHAR"/>
        <COLUMN SOURCE="Col_1" NAME="MATCHNAME" xsi:type="SQLVARCHAR"/>
        <COLUMN SOURCE="Col_2" NAME="CHROMOSOME" xsi:type="SQLVARCHAR"/>
        <COLUMN SOURCE="Col_3" NAME="START_LOCATION" xsi:type="SQLBIGINT"/>
        <COLUMN SOURCE="Col_4" NAME="END_LOCATION" xsi:type="SQLBIGINT"/>
        <COLUMN SOURCE="Col_5" NAME="CENTIMORGANS" xsi:type="SQLFLT4"/>
        <COLUMN SOURCE="Col_6" NAME="MATCHING_SNPS" xsi:type="SQLSMALLINT"/>
    </ROW>
</BCPFORMAT>
Run Code Online (Sandbox Code Playgroud)

当我执行此操作时,我收到此错误消息:

执行 37000(4855)[Microsoft][ODBC SQL Server 驱动程序][SQL Server]格式文件“c:\temp\FormatFile.xml”中的第 2 行时出错:意外元素“BCPFORMAT”。

我无法理解为什么无法识别 BCPFORMAT 元素。XML 根据 Altova XMYSpy 正确格式化。

执行上传的代码是:

bulk insert FF_ChromBrwResults_20190124 from 'c:\temp\temp.csv'
 with (FIELDTERMINATOR = ',',FIRSTROW =1,ROWTERMINATOR = '\n'
,KEEPIDENTITY,CODEPAGE ='OEM',KEEPNULLS, FORMATFILE = 'c:\temp\FormatFile.xml' ) 
Run Code Online (Sandbox Code Playgroud)

CSV 有许多这种格式的行,以换行符结尾:

姓名1,姓名2, 1,48745397,54260005,2.84,1000

我已经尝试从 .NET 代码和在 ODBC 连接工作的 AQT 中执行它;两种方法都产生了相同的错误。

小智 9

发生此错误是因为 xmlns 的 url 包含正确的 HTTPS 是 HTTP。

不正确 = <BCPFORMAT xmlns="https://schemas.microsoft.com/sqlserver/2004/bulkload/format" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

正确 = <BCPFORMAT xmlns="http://schemas.microsoft.com/sqlserver/2004/bulkload/format" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

一旦 CharFixed 的分隔符不是逗号而是长度属性,您的 XML 文件还需要进行一次修改,将所有 CharFixed 转换为 CharTerm。

也将所有类型 SQLVARCHAR 更改为 SQLVARYCHAR

<?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="Col_0" xsi:type="CharTerm" MAX_LENGTH="100" TERMINATOR=","/>
        <FIELD ID="Col_1" xsi:type="CharTerm" MAX_LENGTH="100" TERMINATOR=","/>
        <FIELD ID="Col_2" xsi:type="CharTerm" MAX_LENGTH="3" TERMINATOR=","/>
        <FIELD ID="Col_3" xsi:type="CharTerm" TERMINATOR=","/>
        <FIELD ID="Col_4" xsi:type="CharTerm" TERMINATOR=","/>
        <FIELD ID="Col_5" xsi:type="CharTerm" TERMINATOR=","/>
        <FIELD ID="Col_6" xsi:type="CharTerm" TERMINATOR=","/>
    </RECORD>
    <ROW>
        <COLUMN SOURCE="Col_0" NAME="NAME" xsi:type="SQLVARYCHAR"/>
        <COLUMN SOURCE="Col_1" NAME="MATCHNAME" xsi:type="SQLVARYCHAR"/>
        <COLUMN SOURCE="Col_2" NAME="CHROMOSOME" xsi:type="SQLVARYCHAR"/>
        <COLUMN SOURCE="Col_3" NAME="START_LOCATION" xsi:type="SQLBIGINT"/>
        <COLUMN SOURCE="Col_4" NAME="END_LOCATION" xsi:type="SQLBIGINT"/>
        <COLUMN SOURCE="Col_5" NAME="CENTIMORGANS" xsi:type="SQLFLT4"/>
        <COLUMN SOURCE="Col_6" NAME="MATCHING_SNPS" xsi:type="SQLSMALLINT"/>
    </ROW>
</BCPFORMAT> 
Run Code Online (Sandbox Code Playgroud)


Dav*_*oft 2

这不是一个完整的答案,因为我发现格式文件是一个持久的谜,但尝试让 BCP 生成格式文件,例如:

bcp tempdb.dbo.FF_ChromBrwResults_20190124 format nul -c -x -t "," -f formatfile_gen.xml  -T -S localhost
Run Code Online (Sandbox Code Playgroud)

对于这张表

create table FF_ChromBrwResults_20190124
(
  NAME varchar(100),
  MATCHNAME varchar(100),
  CHROMOSOME varchar(30),
  START_LOCATION bigint,
  END_LOCATION bigint,
  CENTIMORGANS real,
  MATCHING_SNPS smallint
)
Run Code Online (Sandbox Code Playgroud)

输出

<?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="," MAX_LENGTH="100" COLLATION="SQL_Latin1_General_CP1_CI_AS"/>
  <FIELD ID="2" xsi:type="CharTerm" TERMINATOR="," MAX_LENGTH="100" COLLATION="SQL_Latin1_General_CP1_CI_AS"/>
  <FIELD ID="3" xsi:type="CharTerm" TERMINATOR="," MAX_LENGTH="30" COLLATION="SQL_Latin1_General_CP1_CI_AS"/>
  <FIELD ID="4" xsi:type="CharTerm" TERMINATOR="," MAX_LENGTH="21"/>
  <FIELD ID="5" xsi:type="CharTerm" TERMINATOR="," MAX_LENGTH="21"/>
  <FIELD ID="6" xsi:type="CharTerm" TERMINATOR="," MAX_LENGTH="30"/>
  <FIELD ID="7" xsi:type="CharTerm" TERMINATOR="\r\n" MAX_LENGTH="7"/>
 </RECORD>
 <ROW>
  <COLUMN SOURCE="1" NAME="NAME" xsi:type="SQLVARYCHAR"/>
  <COLUMN SOURCE="2" NAME="MATCHNAME" xsi:type="SQLVARYCHAR"/>
  <COLUMN SOURCE="3" NAME="CHROMOSOME" xsi:type="SQLVARYCHAR"/>
  <COLUMN SOURCE="4" NAME="START_LOCATION" xsi:type="SQLBIGINT"/>
  <COLUMN SOURCE="5" NAME="END_LOCATION" xsi:type="SQLBIGINT"/>
  <COLUMN SOURCE="6" NAME="CENTIMORGANS" xsi:type="SQLFLT4"/>
  <COLUMN SOURCE="7" NAME="MATCHING_SNPS" xsi:type="SQLSMALLINT"/>
 </ROW>
</BCPFORMAT>
Run Code Online (Sandbox Code Playgroud)