himanshu.sinha (12/1/2015)
I think using a while loop this should be achievableDECLARE @rng-2 TABLE ( seq int identity(1,1),Id INT, RangeStart BIGINT, RangeEnd BIGINT, Category INT, NumberCount INT)
DECLARE @RNG_output TABLE ( Id INT, Range_No BIGINT, Category INT)
INSERT INTO @rng-2
SELECT 123, 120000006660, 120000006690, 5, 31 UNION ALL
SELECT 123, 120000011660, 120000011670, 5, 11 UNION ALL
SELECT 123, 199000011660, 199000011670, 10, 11 UNION ALL
SELECT 789, 88800001060, 88800001090, 5, 31 UNION ALL
SELECT 789, 99900011660, 99000011675, 10, 16 UNION ALL
SELECT 789, 10000011560, 10000011670, 15, 111 UNION ALL
SELECT 258, 599900010660, 599000010685, 10, 26 UNION ALL
SELECT 258, 510000010560, 510000010565, 10, 6
select * from @rng-2
-- Define variables
Declare @MinValue int
Declare @MaxValue int
Declare @Counter int
Declare @id int
Declare @RangeStart BIGINT
Declare @RangeEnd BIGINT
Declare @Category int
Declare @NumberCount int
Select @MaxValue = max (seq) from @rng-2
Select @counter = 1
--Print 'The max value ' +convert(varchar,@MaxValue )
While ( @counter <= @MaxValue)
Begin
Select
@id = id
,@RangeStart= RangeStart
,@RangeEnd= RangeEnd
,@Category = Category
,@NumberCount = NumberCount
from @rng-2 where seq = @counter
--Print 'The @counter value ' +convert(varchar,@counter )
While (@RangeStart <= @RangeEnd )
Begin
--Print '@RangeStart ' + convert(varchar,@RangeStart)
INSERT INTO @RNG_output (id,Range_No,Category)
SELECT @id ,@RangeStart,@Category
Select @RangeStart = @RangeStart + 1
End
Select @counter = @counter+ 1
-- Resetting the values
Select
@id = 0
,@RangeStart= 0
,@RangeEnd= 0
,@Category = 0
,@NumberCount = 0
End
select * from @RNG_output
As While loops go, that one's pretty fast. It only takes a little over a minute to return all the 3,000,243 rows to the screen using the test data that I used in my previous post above.
When you absolutely must use a While loop (and this case isn't one of those, just to be sure), you can do a couple of things to make it a bit faster. First, use SET NOCOUNT ON. It's not a big thing but it'll cut out a couple of seconds generating all of the singleton row counts. The other thing is to put your outer WHILE loop in an explicit transaction and COMMIT it right after the END of the outer While loop. It doesn't help a huge amount (about 25%) in this case because of the Table Variable and the fact that I have enough memory so it doesn't spool to disk but if need to write to disk, it'll save a lot especially in reducing the time it writes to the log file.
Again, though, it's usually easier to write set based code with a Tally Table or a Tally Function in play. Consider not writing loops for these kinds of things.
--Jeff Moden
Change is inevitable... Change for the better is not.