1

This code works when set @ToDate = '20200311' i.e. when I have hardcoded the specific date, but does not work when I want this to always execute till the current date

The line set @ToDate = select .....getdate.. throws error, can you please help me out and tell me what I should do to rectify?

While @@Fetchstatus =0,

begin 
  set @Fromdate = '20180102';
  set @ToDate = select convert (varchar, getdate(), 112);

  while (@Fromdate < @ToDate) begin
         set @StrQuery = 'INSERT into dbo.Tmp_M_Rates (Rate_Date, Rate_D, Entity, cur) values ('
                         +''''+ CAST (@FromDate AS nvarchar) + ''', ''' + Substring (CONVERT (VARCHAR 
                         (10), @Fromdate, 112),3,8) + ''', ''' + @EntityName + ''', ''' + @Cur + 
                          ''')'
      EXEC (@StrQuery)

      set @Fromdate = dateadd(DAY,1,@Fromdate)
end
9
  • Bad Habits to Kick : Using EXEC() instead of sp_executesql. Parametrise your statements, don't inject the variables. Also Bad habits to kick : declaring VARCHAR without (length) Commented Mar 11, 2020 at 19:15
  • What error does it throw? Give us the details... Commented Mar 11, 2020 at 19:17
  • Not clear why you need a loop here. Perhaps if you provide sample data and desired results. Commented Mar 11, 2020 at 19:18
  • It's not really clear why dynamic sql is needed here either; you could just have a fairly basic insert query in the loop. Commented Mar 11, 2020 at 19:23
  • @DaleK It throws an error saying something is wrong in my syntax Commented Mar 11, 2020 at 19:33

3 Answers 3

1

If Gordon's answer has the correct idea, a far better approach would be to not use any type of recursion. SQL Server is designed for set based methods, and so you should really be using one.

The method you want here is a Tally, which isn't recursive, and isn't limited to 100 loops by default (like an rCTE) because it doesn't loop:

DECLARE @FromDate date = '20180102';

WITH N AS(
    SELECT N
    FROM (VALUES(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL))N(N)),
Tally AS(
    SELECT TOP (DATEDIFF(DAY,@FromDate, GETDATE())+1)
           ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS I
    FROM N N1, N N2, N N3), --1000 rows, add more cross joins to N for more rows
Dates AS(
    SELECT DATEADD(DAY, T.I, @FromDate) AS D
    FROM Tally T)
INSERT INTO dbo.Tmp_M_Rates (Rate_Date, Rate_D, Entity, cur)
SELECT D,
       SUBSTRING(CONVERT(VARCHAR(10), @Fromdate, 112), 3, 8),
       @EntityName,
       @Cur
FROM Dates;
Sign up to request clarification or add additional context in comments.

Comments

0

Just another option with an ad-hoc tally/numbers table

Example

Declare @Date1 date = '2018-01-02'
Declare @Date2 date = getdate()
Declare @Entity varchar(50) ='Entity Name'
Declare @Cur    varchar(50) ='USD'

--INSERT into dbo.Tmp_M_Rates (Rate_Date, Rate_D, Entity, cur) 
Select Rate_Date = D
      ,Rate_D    = dateadd(DAY,1,D)
      ,Entity    = @Entity
      ,Cur       = @Cur
 From (
         Select Top (DateDiff(DAY,@Date1,@Date2)+1) 
               D=DateAdd(DAY,-1+Row_Number() Over (Order By (Select Null)),@Date1) 
         From  master..spt_values n1,master..spt_values n2
      ) A

Generates the Following for INSERT

enter image description here

3 Comments

But the ToDate is not fixed here. If it was fixed , the query works fine when i give a values. But im facing the issue when I want to generate the dynamic query till the current date.ie. today when i run automatically it shuld pick today's system date as 'to date' and tomorrow it should pick 'tomorrow's date' and so on.
@Berry I was guessing how about Date2 = cast(getdate() as date)
@Berry should the second date column be dateadd(DAY,1,D) ? Again without a sample it is hard to determine the actual results
0

You can phrase this as a single query with no dynamic SQL:

WITH dates as (
      SELECT CONVERT(date, '20180102') as dte
      UNION ALL
      SELECT dateadd(day, 1, dte)
      FROM CTE
      WHERE dte <= GETDATE()
     )
INSERT into dbo.Tmp_M_Rates (Rate_Date, Rate_D, Entity, cur)
    SELECT dte, SUBSTRING(CONVERT(VARCHAR(10), @Fromdate, 112), 3, 8),
           @EntityName, @Cur
    FROM dates
    OPTION (MAXRECURSION 0);

I would strongly recommend that you take this or a similar approach.

3 Comments

Why an rCTE? For 2018 to date, that's over 700 loops; it's really not much better than a WHILE. A Tally would be so much faster. An rCTE, like the name suggests, is still a form of recursion; just like a Loop.
@Larnu . . . A single query is much better than a while. Admittedly, the comparison is different, but recursive CTEs have very reasonable performance -- a bit worse than say a numbers table -- but perfectly reasonable for most problems. Here is an example: strictlysql.blogspot.com/2010/01/….
I disagree. An rCTE is a very slow method. Hidden RBAR: Counting with Recursive CTE's, rCTE vs Tally. A TAlly is significantly faster.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.