11

I am trying to batch inserting rows from one table to another.

DECLARE @batch INT = 10000;

WHILE @batch > 0
BEGIN
BEGIN TRANSACTION

    INSERT into table2
    select top (@batch) *
    FROM table1

    SET @batch = @@ROWCOUNT

COMMIT TRANSACTION

END

It runs on the first 10,000 and inserts them. Then i get error message "Cannot insert duplicate key" which its trying to insert the same primary key so i assume its trying to repeat the same batch. What logic am i missing here to loop through the batches? Probably something simple but i cant figure it out.

Can anyone help? thanks

1
  • Another alternative is this Commented Jan 24, 2020 at 16:17

3 Answers 3

18

Your code keeps inserting the same rows. You can avoid it by "paginating" your inserts:

DECLARE @batch INT = 10000;
DECLARE @page INT = 0
DECLARE @lastCount INT = 1

WHILE @lastCount > 0
BEGIN
BEGIN TRANSACTION

    INSERT into table2
    SELECT col1, col2, ... -- list columns explicitly
    FROM    ( SELECT    ROW_NUMBER() OVER ( ORDER BY YourPrimaryKey ) AS RowNum, *
              FROM      table1
            ) AS RowConstrainedResult
    WHERE   RowNum >= (@page * @batch) AND RowNum < ((@page+1) * @batch)
    SET @lastCount = @@ROWCOUNT
    SET @page = @page + 1

COMMIT TRANSACTION

END
Sign up to request clarification or add additional context in comments.

Comments

6

You need some way to eliminate existing rows. You seem to have a primary key, so:

INSERT into table2
   SELECT TOP (@batch) *
   FROM table1 t1
   WHERE NOT EXISTS (SELECT 1 FROM table2 t2 WHERE t2.id = t1.id);

Comments

1

How about using the designated set of keywords for this problem : OFFSET - FETCH

DECLARE @batch INT = 10000;
DECLARE @lastCount INT = 1;
DECLARE @totalCount INT = 0;

WHILE @lastCount > 0
BEGIN
    BEGIN TRANSACTION

    INSERT into table2
    select *
    FROM table1
    ORDER BY <id>
    OFFSET @totalCount ROWS
    FETCH NEXT @batch ROWS ONLY

    SET @lastCount = @@ROWCOUNT
    SET @totalCount += @lastCount

    COMMIT TRANSACTION

END

1 Comment

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.