SQL 批量插入忽略第一个数据行

SQL Bulk insert ignores first data row

我正在尝试使用批量插入(带有 unix 样式行终止符的 UTF-8)将管道分隔文件导入临时 table,但它一直忽略第一个数据行(header),我不知道为什么。 将 | 添加到 header 行也无济于事...

文件内容:

SummaryFile_20191017140001.dat|XXXXXXXXXX|FIL-COUNTRY|128
File1_20191011164611.dat|2|4432|2|Imported||
File2_20191011164611.dat|3|4433|1|Imported||
File3_20191011164611.dat|4|4433|2|Imported||
File4_20191011164611.dat|5|4434|1|Imported|INV_ERROR|
File5_20191011164611.dat|6|4434|2|Imported||
File6_20191011164611.dat|7|4434|3|Imported||

批量插入没有抛出错误,但它一直忽略第一行数据 (File1_...)

SQL 下面:

IF OBJECT_ID('tempdb..#mycsv') IS NOT NULL
DROP TABLE #mycsv

create table #mycsv
    (
        tlr_file_name   varchar(150) null,
        tlr_record_id   int null,
        tlr_pre_invoice_number  varchar(50) null,
        tlr_pre_invoice_line_number varchar(50) null,
        tlr_status  varchar (30) null,
        tlr_error_code  varchar(30) null,
        tlr_error_message   varchar (500) null)

bulk insert #mycsv 
from 'D:\TestData\Test.dat' 
with (
    rowterminator = '0x0A',
    fieldTerminator = '|',
    firstrow = 2, 
    ERRORFILE = 'D:\TestData\Import.log')

select * from #mycsv

这真的很困扰我,因为我真的不知道我错过了什么。 如果我指定 FirstRow = 1 脚本将抛出: Bulk load data conversion error (type mismatch or invalid character for the specified codepage) for row 1, column 2 (tlr_record_id).

提前致谢!

"UTF-8 with unix style row terminator" 我假设您使用的 SQL 服务器版本不支持 UTF-8。来自 BULK INSERT (Transact-SQL)

** Important ** Versions prior to SQL Server 2016 (13.x) do not support code page 65001 (UTF-8 encoding).

如果您使用2016+,那么请指定UTF-8的代码页:

BULK INSERT #mycsv
FROM 'D:\TestData\Test.dat'
WITH (ROWTERMINATOR = '0x0A',
      FIELDTERMINATOR = '|',
      FIRSTROW = 1,
      CODEPAGE = '65001',
      ERRORFILE = 'D:\TestData\Import.log');

如果您没有使用 SQL Server 2016+,那么您 不能 使用 BULK INSERT 导入 UTF-8 文件;您将不得不使用不同的代码页或使用不同的工具。


另请注意,上述文件说明如下:

The FIRSTROW attribute is not intended to skip column headers. Skipping headers is not supported by the BULK INSERT statement. When skipping rows, the SQL Server Database Engine looks only at the field terminators, and does not validate the data in the fields of skipped rows.

如果您要跳过行,您仍然需要确保该行有效,但不是为了跳过 headers。这意味着您应该使用 FIRSTROW = 1 并按照@sarlacii 指出的那样修复 header 行。

当然,如果您使用的是旧版本的 SQL 服务器,这并不能解决代码页问题;我的观点是,您必须在 2014 年及之前使用不同的技术。

要将行有效地导入 SQL 数据库,使 header 格式与数据行相匹配很重要。像这样将缺少的分隔符添加到 header 并再次尝试导入:

SummaryFile_20191017140001.dat|XXXXXXXXXX|FIL-COUNTRY|128|||

header 中的字段数与数据字段必须匹配,否则该行将被忽略,第一个令人满意的 "data" 行将被视为 header.