John Sterrett blog|twitter asked a question about “How do I loop by rowcount in SSIS? I have a table with 5 million IDs and would like to loop to process 10K at a time. #sqlhelp”
This cannot be done natively in SSIS but you could create a stored procedure that uses the concept known as “poor man’s cursor” to split it in batches.
I included a template of code that I useĀ to create smaller transactions that do not block normal users accessing the same tables
Let me know what you think.
/*************************************************************************************** * Name: Poor mans cursor example for batch processing * Author: Luke Jian - luke(a.t)sqlpositive.com * Creation Date: 11/02/11 * Purpose: Template for batch processing using Poor man's cursor ***************************************************************************************/ DECLARE @RowStart [INT] DECLARE @RowEnd [INT] DECLARE @RowToDo [INT] DECLARE @RowDone [INT] DECLARE @BatchSize [INT] BEGIN -- Load Users To Enable IF ( OBJECT_ID('[TempDB]..[#PoorManCursor]') IS NOT NULL ) DROP TABLE [#PoorManCursor] SELECT --DISTINCT [ID] = IDENTITY ( [INT], 1, 1) --.. SOME other rows INTO [#PoorManCursor] FROM dbo.BaseTables --ORDER BY [Whatever column for batch order] -- Add index to temp table -- because table may easily exceed 10,000,000 rows CREATE UNIQUE CLUSTERED INDEX [UCPoorManCursorID] ON [#PoorManCursor] ( [ID] ) -- Set up batching SELECT @RowStart = 1, @RowEnd = @BatchSize, --can use 10K @RowToDo = MAX([ID]), @RowDone = 0 FROM [#PoorManCursor] PRINT CAST(@RowToDo AS [VARCHAR]) + ' records to be processed.' -- Process batch WHILE ( @RowStart <= @RowToDo ) BEGIN BEGIN TRANSACTION -- Load PoorManCursor_Tracking INSERT INTO [dbo].[SomeTargetTable] ( [col1], [col2], [col3], [col4] ) SELECT [col1], [col2], [col3], [col4], CURRENT_TIMESTAMP FROM #PoorManCursor WHERE [ID] >= @RowStart AND [ID] <= @RowEnd COMMIT TRANSACTION PRINT CAST(@RowCount AS [VARCHAR]) + ' records completed in this batch' SET @RowDone = @RowDone + @RowCount SET @RowStart = @RowStart + @BatchSize SET @RowEnd = @RowEnd + @BatchSize END PRINT CAST(@RowDone AS [VARCHAR]) + ' total records processed.' IF ( OBJECT_ID('[TempDB]..[#PoorManCursor]') IS NOT NULL ) DROP TABLE [#PoorManCursor] END