• himanshu.sinha (12/1/2015)


    I think using a while loop this should be achievable

    DECLARE @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


    RBAR is pronounced "ree-bar" and is a "Modenism" for Row-By-Agonizing-Row.
    First step towards the paradigm shift of writing Set Based code:
    ________Stop thinking about what you want to do to a ROW... think, instead, of what you want to do to a COLUMN.

    Change is inevitable... Change for the better is not.


    Helpful Links:
    How to post code problems
    How to Post Performance Problems
    Create a Tally Function (fnTally)