如何确保 BULK INSERT 将按顺序插入我的平面文件行?
Posted
技术标签:
【中文标题】如何确保 BULK INSERT 将按顺序插入我的平面文件行?【英文标题】:How can I ensure that a BULK INSERT will insert my flat file's rows in order? 【发布时间】:2016-06-09 13:04:02 【问题描述】:我有一个由多行文本组成的平面文件,没有字段分隔符(我按位置解析它们)并且用换行符作为行分隔符。基本上是这样的:
FIELD1AFIELD2AFIELD3AFIELD4A...
FIELD1BFIELD2BFIELD3BFIELD4B...
FIELD1CFIELD2CFIELD3CFIELD4C...
在将其解析到最终表之前,我使用以下命令将其批量插入到临时表中:
BULK INSERT TEMPTABLE
FROM 'c:\location\file'
WITH (FIELDTERMINATOR= '',ROWTERMINATOR = '\n',MAXERRORS = 0)
现在,第一行和最后一行用作文件的标题和结尾,并包含特殊信息。因此,它们不遵循“FIELD1AFIELD2AFIELD3AFIELD4A ...”的相同模式,因此我需要考虑它们。此外,我需要专门在另一个表中插入标题行的信息。
但是当我运行批量插入时,行并没有按顺序插入到临时表中,所以我不能只假设顶部寄存器将是标题,而最后一个寄存器将是尾部。
有没有办法强制批量插入不遵循平面文件中的行顺序?我没有“键列”,也没有索引,也没有文件中的任何内容,并且无法在此文件中插入行号(我需要保留收到的内容,并且太大而无法复制或修改无论如何)。
谢谢
【问题讨论】:
"但是当我运行批量插入时,行没有按顺序插入"你怎么知道的?我问是因为SELECT
不一定会按照插入的顺序返回它们。
在你的临时表上创建一个标识列怎么样?批量插入将按文件顺序插入,您的问题是您的选择可能不会按顺序排列,因此您添加一个标识列并选择按它排序。
@RBarryYoung:嗯,这就是问题所在。当我从临时表过渡到最终表时,我会通过 INSERT INTO...SELECT 来完成。此外,在需要标题的第一行时,我做了一个 SELECT TOP 1 * FROM TEMPTABLE,所以我知道该查询没有返回标题行
@JorgeCampos:如果我在临时表中添加标识列,我会收到此错误:Msg 4866, Level 16, State 1, Line 1 批量加载失败。数据文件中第 1 行第 54 列的列太长。验证是否正确指定了字段终止符和行终止符。消息 7399,级别 16,状态 1,第 1 行链接服务器“(null)”的 OLE DB 提供程序“BULK”报告了错误。提供商没有提供有关该错误的任何信息。消息 7330,级别 16,状态 2,第 1 行无法从链接服务器“(null)”的 OLE DB 提供程序“BULK”获取行。
很可能是因为它试图将第一个值插入 ID 列。您必须使用格式文件,请参阅此线程:***.com/questions/14711814/…
【参考方案1】:
我记得(有一段时间没做过了)以下是适合我的步骤:
不要使用临时表,而是使用永久表(名称 Temp_<something>
,如果需要),您只需在使用 BULK INSERT
之前删除/截断即可。
更改 Temp_<something>
以添加 ID 列并将其设为此表的聚集主键。
创建视图:
.
CREATE VIEW Temp_something_View As
SELECT
(every column EXCEPT the ID column)
FROM Temp_something
GO
.
-
现在批量插入视图而不是表。
现在 ID 值最低和最高的行应该是输入源的第一行和最后一行。
当您需要源输入顺序中的行时,只需使用ORDER BY ID
从表中选择。否则它将根据某些物理分配约束而不是按照您想要的逻辑顺序返回它们。
【讨论】:
如果我在临时表中添加该列(作为永久表)然后创建视图,当我执行批量插入时,我会收到以下消息:“消息 2601,级别 14,状态 1,第 1 行无法插入重复键行,重复键为确保从源数据集中以正确的顺序选择数据。
【讨论】:
以上是关于如何确保 BULK INSERT 将按顺序插入我的平面文件行?的主要内容,如果未能解决你的问题,请参考以下文章
获取 Bulk.Insert() -Mongoskin 的插入 ID
bulk.insert(doc) 默认值无法插入 MongoDB nodejs