没有标识列时如何进行批量插入?

时间:2016-03-03 20:04:54

标签: sql sql-server bulkinsert

包含百万行,两列的表。

code | name
xyz  | product1
abc  | Product 2
...
...

我想通过插入/ select查询以小批量(10000)进行插入。

如果没有用于创建批处理的标识密钥,我们如何才能执行此操作?

2 个答案:

答案 0 :(得分:2)

您可以在LEFT OUTER JOIN语句中使用SELECT来识别INSERT表中尚未存在的记录,然后使用TOP获取前一个10000数据库找到。类似的东西:

INSERT INTO tableA
SELECT TOP 10000 code, name
FROM tableB LEFT OUTER JOIN tableA ON tableB.Code = tableA.Code
WHERE tableA.Code IS NULL;

然后一遍又一遍地运行,直到它满了。

您还可以使用窗口函数批处理:

INSERT INTO tableA
SELECT code, name
FROM (
       SELECT code, name, ROW_NUMBER() OVER (ORDER BY name)  as rownum         
       FROM tableB
     )
WHERE rownum BETWEEN 1 AND 100000;

然后继续更改BETWEEN以获取您的批次。就个人而言,如果我必须这样做,我会使用第一种方法,因为它可以保证捕获TableA中尚未存在的所有内容。

此外,如果在此批处理过程中tableb有可能获得记录,那么选项1肯定会更好。基本上,使用option2,它将动态确定row_number(),因此新插入的记录将导致记录在批量中间出现时被遗漏。

如果TableB是静态的,那么选项2可能会更快,因为数据库只需要对记录进行排序和编号,而不必将HUGE表连接到HUGE表,然后获取10000条记录。

答案 1 :(得分:0)

您可以对SELECT进行分页,并按批次/页面大小选择记录10000或者您需要的任何内容并插入目标表中。在下面的示例中,您需要为希望拥有的批量大小的每次迭代更改@Min和@Max的值。

INSERT INTO EmployeeNew
SELECT Name
FROM
(
    SELECT DENSE_RANK OVER(ORDER BY EmployeeId) As Rank, Name
    FROM Employee
) AS RankedEmployee
WHERE Rank >= @Min AND Rank < @Max