Search code examples
sqlloopsstored-proceduressql-server-2014-express

SQL, How to loop for a date list using each as parameter for an Procedure?


I have an Procedure that receives an specific date as parameter ie Exec ProcDB '20150428'

frequently I need to run this procedure for many dates and usually I retype Exec ProcDB 'date1' GO Exec ProcDB 'date2'go..... I think it's not smart, so

I can get the valid list of dates using a Select Distinct [dates] From Table1 Order By [dates].

So I want to create a new Procedure that receives Start_Dt and End_Dt and it loops for all dates that my select distinct returns where its between including Start_Dt and End_Dt.

ie something like:

Create ProcDBlist Start_Dt as date, End_Dt as date
For each date in: Select Distinct [date] from [table1] where [date] >= @Start_Dt and [date] <= @End_dt
Do: Exec ProcDB 'Date n'
End

UPDATED:

Final solution:

Create procedure [dbo].[ProcessDBRange] (@Start_dt as varchar(15) =null, @End_dt as varchar(15) =null)
As
Begin
DECLARE @date as varchar(15)

DECLARE Cursor_ProcessDB CURSOR FOR
    Select Distinct Convert(varchar(15), [date], 112) as [date]
    From [Prices]
    Where [date] >= @Start_dt and [date] <= @End_dt
    Order By [date]

OPEN Cursor_ProcessDB

FETCH next FROM Cursor_ProcessDB
INTO @date

WHILE @@FETCH_STATUS = 0

BEGIN

Exec ProcessDB @date

FETCH next FROM Cursor_ProcessDB
INTO @date

END
CLOSE Cursor_ProcessDB
DEALLOCATE Cursor_ProcessDB
End

Solution

  • This can be accomplished by using a cursor.
    Basically, it goes like this:

    DECLARE @Date datetime -- a local variable to get the cursor's result
    
    DECLARE DatesCursor CURSOR FOR
      Select Distinct [dates] where [dates] between @Start_Dt and @End_Dt From Table1 Order By [dates]. -- the query that the cursor iterate on
    
    OPEN DatesCursor
    FETCH NEXT FROM DatesCursor INTO @Date 
    WHILE @@FETCH_STATUS = 0 -- this will be 0 as long as the cursor returns a result
      BEGIN
        Exec ProcDB @Date
        FETCH NEXT FROM DatesCursor INTO @Date -- don't forget to fetch the next result inside the loop as well!
      END
    -- cleanup - Very important!
    CLOSE DatesCursor 
    DEALLOCATE DatesCursor 
    

    Edit
    I've just read the link that zimdanen gave you in the comments, I must say I think in this case it may be better than a using a cursor.

    Edit #2

    First, change OPEN sub to OPEN cursor_name. Second, use CONVERT to get the date as a string. Make sure you convert with the correct style, otherwise you are prone to get incorrect dates and/or exceptions.