All this work for nothing. setting xsi:type to CharFixed instead of NCharFixed solved that problem, even though I'm using Unicode. Now I'm dealing with weird characters in my data (that show up as normal text in the input file).
SQL Server: Bulk load data conversion error
-
17-01-2022 - |
Question
I'm trying to load some data from a fixed width text file into a view, with the insertion intercepted by an instead-of trigger.
The debug select that's supposed to output the values from INSERTED in the trigger doesn't get triggered, so I suspect the point of failure is the bulk insert itself.
Here are the details: Here's what I'm using:
The initiating bulk insert command looks like this:
BULK INSERT Staging.vViewSolelyForInsertion
FROM 'X:\path\to\datafile.txt'
WITH
(
FORMATFILE='X:\path\to\formatfile.xml',
FIRE_TRIGGERS,
ERRORFILE='X:\path\to\Error.log'
)
CREATE command used for Staging.vViewSolelyForInsertion:
CREATE VIEW Staging.vViewSolelyForInsertion
AS
SELECT
CONVERT(NVARCHAR(4), NULL, 0) AS Door,
CONVERT(NVARCHAR(9), NULL, 0) AS Chair,
CONVERT(NVARCHAR(24), NULL, 0) AS Office,
CONVERT(NVARCHAR(10), NULL, 0) AS Telephone,
CONVERT(NVARCHAR(4), NULL, 0) AS Cup,
CONVERT(NVARCHAR(1), NULL, 0) AS Headphones,
CONVERT(NVARCHAR(20), NULL, 0) AS Mouse,
CONVERT(NVARCHAR(12), NULL, 0) AS Keyboard
CREATE command used to create the trigger
CREATE TRIGGER Staging.ON_INSERT_Staging_vViewSolelyForInsertion
ON Staging.vRefViewSolelyForInsertion
BEGIN
SELECT * FROM INSERTED -- debug, the error message appears before this point.
/*
This table exists to generate the InternalId.
*/
DECLARE @tbl TABLE
(
InternalId UNIQUEIDENTFIER NOT NULL DEFAULT NEWID(),
Door,
Chair,
Office,
Telephone,
Cup,
Headphones,
Mouse,
Keyboard
)
INSERT INTO @tbl
(
Door,
Chair,
Office,
Telephone,
Cup,
Headphones,
Mouse,
Keyboard
)
SELECT
i.Door,
i.Chair,
i.Office,
i.Telephone,
i.Cup,
i.Headphones,
i.Mouse,
i.Keyboard
FROM INSERTED i
SELECT * FROM @tbl -- 2nd debug
INSERT INTO Staging.ActualTable
(
InternalId,
Door,
Chair,
Office,
Telephone,
Cup,
Headphones,
Mouse,
Keyboard
)
SELECT
-- Lots of processing goes on here.
t.InternalId,
ProcessDoor(t.Door, t.InternalId),
ProcessChair(t.Chair, t.InternalId),
ProcessOffice(t.Office, t.InternalId),
ProcessTelephone(t.Telephone, t.InternalId),
ProcessCup(t.Cup, t.InternalId),
ProcessHeadphones(t.Headphones, t.InternalId),
ProcessMouse(t.Mouse, t.InternalId),
ProcessKeyboard(t.Keyboard, t.InternalID)
FROM @tbl t
DELETE FROM @tbl
END
This is the format file I'm using
<?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="NCharFixed" LENGTH="4" COLLATION="SQL_Latin1_General_CP1_CI_AS"/>
<FIELD ID="2" xsi:type="NCharFixed" LENGTH="9" COLLATION="SQL_Latin1_General_CP1_CI_AS"/>
<FIELD ID="3" xsi:type="NCharFixed" LENGTH="24" COLLATION="SQL_Latin1_General_CP1_CI_AS"/>
<FIELD ID="4" xsi:type="NCharFixed" LENGTH="10" COLLATION="SQL_Latin1_General_CP1_CI_AS"/>
<FIELD ID="5" xsi:type="NCharFixed" LENGTH="4" COLLATION="SQL_Latin1_General_CP1_CI_AS"/>
<FIELD ID="6" xsi:type="NCharFixed" LENGTH="4" COLLATION="SQL_Latin1_General_CP1_CI_AS"/>
<FIELD ID="7" xsi:type="NCharFixed" LENGTH="1" COLLATION="SQL_Latin1_General_CP1_CI_AS"/>
<FIELD ID="8" xsi:type="NCharFixed" LENGTH="10" COLLATION="SQL_Latin1_General_CP1_CI_AS"/>
<FIELD ID="9" xsi:type="NCharFixed" LENGTH="10" COLLATION="SQL_Latin1_General_CP1_CI_AS"/>
<FIELD ID="10" xsi:type="NCharFixed" LENGTH="4" COLLATION="SQL_Latin1_General_CP1_CI_AS"/>
<FIELD ID="11" xsi:type="NCharFixed" LENGTH="9" COLLATION="SQL_Latin1_General_CP1_CI_AS"/>
<FIELD ID="12" xsi:type="NCharFixed" LENGTH="20" COLLATION="SQL_Latin1_General_CP1_CI_AS"/>
<FIELD ID="13" xsi:type="NCharFixed" LENGTH="12" COLLATION="SQL_Latin1_General_CP1_CI_AS"/>
<FIELD ID="14" xsi:type="CharTerm" TERMINATOR="\r\n" COLLATION="SQL_Latin1_General_CP1_CI_AS"/>
</RECORD>
<ROW>
<COLUMN SOURCE="1" NAME="Door" LENGTH="4" xsi:type="SQLNVARCHAR"/>
<COLUMN SOURCE="2" NAME="Chair" LENGTH="9" xsi:type="SQLNVARCHAR"/>
<COLUMN SOURCE="3" NAME="Office" LENGTH="24" xsi:type="SQLNVARCHAR"/>
<COLUMN SOURCE="4" NAME="Telephone" LENGTH="10" xsi:type="SQLNVARCHAR"/>
<COLUMN SOURCE="5" NAME="Cup" LENGTH="4" xsi:type="SQLNVARCHAR"/>
<COLUMN SOURCE="7" NAME="Headphones" LENGTH="1" xsi:type="SQLNVARCHAR"/>
<COLUMN SOURCE="12" NAME="Mouse" LENGTH="20" xsi:type="SQLNVARCHAR"/>
<COLUMN SOURCE="13" NAME="Keyboard" LENGTH="12" xsi:type="SQLNVARCHAR"/>
</ROW>
</BCPFORMAT>
The data file consists of \r\n terminated lines, no separators between data fields and is saved in unicode. Each line is 138 characters long, plus the \r\n at the end of the line.
The error I get is the following:
Bulk load data conversion error (truncation) for row 1, column 2 (Chair).
The field lengths from the ImportFile.xml are the same as the column lengths in the ImportFile.xml are the same as the nvarchar lenghts in the Staging.vViewSolelyForInsertion. As mentioned above (I know it's a long time ago), the first debug statement in the trigger doesn't get executed, leading me to think that it's the BULK INSERT that fails.
Thanks in advance!
Solution