没有标识列怎么批量插入?

How to do batch insert when there is no identity column?

Table 百万行,两列。

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

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

创建批次时没有身份密钥怎么办?

您可以在 SELECT 语句中使用 LEFT OUTER JOIN 来识别 INSERT table 中不存在的记录,然后使用 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肯定更好。本质上,使用选项 2,它将即时确定 row_number(),因此新插入的记录如果出现在批次中间,将导致记录丢失。

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

您可以对 SELECT 和 select 记录按 batch/page 大小(例如 10000 或任何您需要的大小)进行分页,然后插入目标 table。在下面的示例中,您必须为您希望拥有的批量大小的每次迭代更改 @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