Мое предложение состоит в том, чтобы использовать прямую sql и потерять логи курсора c. В любое время это будет более эффективно, быстрее и дешевле
Например: следующий запрос может дать вам last_consecutive_count
CREATE TABLE dbo.t
(
USER_ID INT
,YEAR INT
,MONTH INT
,HOURS_REPORTED INT
);
insert into dbo.t
VALUES
( 254, '2017', '12', 0 ),
( 254, '2018', '01', 8 ),
( 254, '2018', '02', 11 ),
( 254, '2018', '03', 16 ),
( 254, '2018', '04', 12 ),
( 254, '2018', '05', 16 ),
( 254, '2018', '06', 20 ),
( 254, '2018', '07', 14 ),
( 254, '2018', '08', 12 ),
( 254, '2018', '09', 11 ),
( 254, '2018', '10', 22 ),
( 254, '2018', '11', 10 ),
( 254, '2018', '12', 6 ),
( 254, '2019', '01', 11 ),
( 254, '2019', '02', 12 ),
( 254, '2019', '03', 5 ),
( 254, '2019', '04', 12 ),
( 254, '2019', '05', 10 ),
( 254, '2019', '06', 9 ),
( 254, '2019', '07', 10 ),
( 254, '2019', '08', 9 ),
( 254, '2019', '09', 0 ),
( 254, '2019', '10', 4 ),
( 254, '2019', '11', 8 ),
( 254, '2019', '12', 0 ),
( 254, '2020', '01', 0 ),
( 254, '2020', '02', 5 ),
( 254, '2020', '03', 7 )
WITH data
AS (SELECT *
,CAST(CONCAT(YEAR, '-', MONTH, '-01') AS DATE) AS dt
,ROW_NUMBER() OVER (ORDER BY YEAR desc, MONTH desc) AS rnk
,ROW_NUMBER() OVER (partition by case when hours_reported=0 then 1 end ORDER BY YEAR desc, MONTH desc) AS rnk2
,DATEADD(MONTH, -ROW_NUMBER() OVER (ORDER BY YEAR, MONTH), CAST(CONCAT(YEAR, '-', MONTH, '-01') AS DATE)) AS grp
FROM dbo.t
WHERE USER_ID = 254 /* you can parameterize this in your sql server function*/
)
,last_val
as(SELECT *
,case when hours_reported<>0 then rnk else rnk-rnk2 end as val1
,rank() over(order by case when hours_reported<>0 then rnk else rnk-rnk2 end) as rnk_min
FROM data
)
select count(*) as last_consec_cnt
from last_val
where rnk_min=1
+----------------------+
| last_consecutive_cnt |
+----------------------+
| 1 |
+----------------------+
Вы можете поместить это в функцию и передать user_id таблица ..
Вот ссылка на дб скрипку. https://dbfiddle.uk/?rdbms=sqlserver_2016&fiddle=9ac60e62a99e2465cc8e979ae9f29f7c