使用游标将数据从一个表复制到另一个表

时间:2011-11-24 18:28:14

标签: sql-server sql-server-2008-r2 database-cursor

我有一个非常大的表(大约1300万行)叫做Book。我想在Book表的一列中设置主键,但由于它是一个非常大的表,服务器在更新期间崩溃。它耗尽内存。所以我创建了一个BookTemp表,我在这个空表中设置了所有主键,然后我想将Book中的数据插入到BookTemp表中。但是,如果我立即这样做,内存再次耗尽。所以我想使用游标来每次插入10,000行然后擦除RAM但我对游标很新,所以在这一点上我希望得到你的帮助。

我使用SQL Server 2008 R2

2 个答案:

答案 0 :(得分:1)

我建议使用while循环遍历临时表。示例here应该让您入门。

或者你可以修改一下:

DECLARE @counter AS INT = 0;
DECLARE @batch_size AS INT = 10000;
WHILE (@counter < (SELECT MAX(id) FROM temp_table))
BEGIN
  INSERT INTO the_table
  SELECT * FROM temp_table
  WHERE id BETWEEN @counter AND (@counter + @batch_size - 1);

  SET @counter = @counter + @batch_size;
END

答案 1 :(得分:0)

执行以下三个命令后,将通过清理缓存来释放SQL Server的内存。

DBCC FREESYSTEMCACHE
DBCC FREESESSIONCACHE
DBCC FREEPROCCACHE 

但是,它可以用于正在进行的操作,所以请看插入查询,插入每个10000后,通过执行上面的DBCC命令清除内存。

DECLARE @counter INT = 1
DECLARE cur_Data_Transfer CURSOR FOR  -- Cursor declared
SELECT column1, column2  -- select desired columns
FROM Book 

OPEN cur_Data_Transfer  --Opening Cursor
FETCH NEXT FROM cur_Data_Transfer INTO @column1, @column2  --Put values to variable

WHILE @@FETCH_STATUS = 0  -- Faching is success
BEGIN  
       INSERT INTO BookTemp (column1, column2) -- Inserting to temptable
            VALUES(@column1, @column2)
       IF @counter = 10000
       BEGIN    
        DBCC FREESYSTEMCACHE -- Clear System Cache
        DBCC FREEPROCCACHE   -- Clear Proc Cache
        SET @counter = 0     -- Restarting counter
       END
       FETCH NEXT FROM cur_Data_Transfer INTO @column1, @column2
       SET @counter = @counter + 1
END  
CLOSE cur_Data_Transfer  -- Closing cursor
DEALLOCATE cur_Data_Transfer -- De-allocating