使用FIRSTROW参数的SQL批量插入会跳过以下行

gib*_*bbo 8 sql bulkinsert sql-server-2005

我似乎无法弄清楚这是怎么回事.

以下是我尝试批量插入SQL Server 2005的文件示例:

***A NICE HEADER HERE***
0000001234|SSNV|00013893-03JUN09
0000005678|ABCD|00013893-03JUN09
0000009112|0000|00013893-03JUN09
0000009112|0000|00013893-03JUN09
Run Code Online (Sandbox Code Playgroud)

这是我的批量插入声明:

BULK INSERT sometable
FROM 'E:\filefromabove.txt
WITH
(
FIRSTROW = 2,
FIELDTERMINATOR= '|',
ROWTERMINATOR = '\n'
)
Run Code Online (Sandbox Code Playgroud)

但是,出于某种原因,我能得到的唯一输出是:

0000005678|ABCD|00013893-03JUN09
0000009112|0000|00013893-03JUN09
0000009112|0000|00013893-03JUN09
Run Code Online (Sandbox Code Playgroud)

除非我完全删除标题并且不使用FIRSTROW参数,否则总是会跳过第一条记录.这怎么可能?

提前致谢!

Cad*_*oux 14

我不认为你可以使用BULK INSERT/ 跳过不同格式的行BCP.

当我运行这个:

TRUNCATE TABLE so1029384

BULK INSERT so1029384
FROM 'C:\Data\test\so1029384.txt'
WITH
(
--FIRSTROW = 2,
FIELDTERMINATOR= '|',
ROWTERMINATOR = '\n'
)

SELECT * FROM so1029384
Run Code Online (Sandbox Code Playgroud)

我明白了:

col1                                               col2                                               col3
-------------------------------------------------- -------------------------------------------------- --------------------------------------------------
***A NICE HEADER HERE***
0000001234               SSNV                                               00013893-03JUN09
0000005678                                         ABCD                                               00013893-03JUN09
0000009112                                         0000                                               00013893-03JUN09
0000009112                                         0000                                               00013893-03JUN09
Run Code Online (Sandbox Code Playgroud)

看起来它需要'|' 甚至在标题数据中,因为它读取到第一列 - 将换行符吞入第一列.显然,如果你包含一个字段终止符参数,它期望每一行必须有一个.

您可以使用预处理步骤剥离行.另一种可能性是仅选择完整的行,然后处理它们(排除标题).或者使用可以处理此问题的工具,例如SSIS.


Mar*_*ell 8

也许检查标题是否与实际数据行(如指定的那样ROWTERMINATOR)具有相同的行结尾?

更新:来自MSDN:

FIRSTROW属性不用于跳过列标题.BULK INSERT语句不支持跳过标头.在跳过行时,SQL Server数据库引擎仅查看字段终止符,并且不会在跳过的行的字段中验证数据.


nor*_*ndo 6

我发现最简单的方法是将整行读入一列,然后使用XML解析数据.

IF (OBJECT_ID('tempdb..#data') IS NOT NULL) DROP TABLE #data
CREATE TABLE #data (data VARCHAR(MAX))

BULK INSERT #data FROM 'E:\filefromabove.txt' WITH (FIRSTROW = 2, ROWTERMINATOR = '\n')

IF (OBJECT_ID('tempdb..#dataXml') IS NOT NULL) DROP TABLE #dataXml
CREATE TABLE #dataXml (ID INT NOT NULL IDENTITY(1,1) PRIMARY KEY CLUSTERED, data XML)

INSERT #dataXml (data)
SELECT CAST('<r><d>' + REPLACE(data, '|', '</d><d>') + '</d></r>' AS XML)
FROM #data

SELECT  d.data.value('(/r//d)[1]', 'varchar(max)') AS col1,
        d.data.value('(/r//d)[2]', 'varchar(max)') AS col2,
        d.data.value('(/r//d)[3]', 'varchar(max)') AS col3
FROM #dataXml d
Run Code Online (Sandbox Code Playgroud)