问题
I am trying to use BULK INSERT
to insert a large amount of binary files with metadata into a SQL Server table. I want to only specify a subset of the columns to use (most importantly, the PK is a UniqueIdentifier
and I want SQL Server to generate this field). And so I must use a model file.
Not using a model file (entering data for all columns) works fine with this file:
00000000-F436-49D0-B5A9-02DAB2E03F45, B, , , , JVBERio4MjEzNQ0KJSVFT0Y=, 109754, 2017-12-14 14:53:23, 2017-12-14 14:53:23, number, name
And this statement:
BULK INSERT Documents
FROM 'c:\temp\testdata.txt'
WITH
(
FIELDTERMINATOR = ',',
ROWTERMINATOR = '\n',
ROWS_PER_BATCH = 1000,
FIRSTROW = 1,
TABLOCK
)
But when I try to use a model file, I have run into two different problems. Firstly, when using a model file that specifies all columns:
<?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>
and this statement:
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
I get this error:
Msg 4866, Level 16, State 7, Line 1
The bulk load failed. The column is too long in the data file for row 1, column 2. Verify that the field terminator and row terminator are specified correctly.Msg 7399, Level 16, State 1, Line 1
The OLE DB provider "BULK" for linked server "(null)" reported an error. The provider did not give any information about the error.Msg 7330, Level 16, State 2, Line 1
Cannot fetch a row from OLE DB provider "BULK" for linked server "(null)".`
And when using this reduced model file (and atext file with fewer values):
<?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>
I get:
Msg 257, Level 16, State 3, Line 1
Implicit conversion from data type datetime to int is not allowed. Use the CONVERT function to run this query.
回答1:
I'd suggest to import this data into a tolerant staging table and continue from there. Just one observation:
<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">
Correspond to
<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 seems to be an INT
(8 byte is to much though), while 8 and 9 point to date value (by the column's names and types), while the <FIELD>
definition is not consistent.
来源:https://stackoverflow.com/questions/47829486/failing-to-bulk-insert-with-xml-model