Can't test on SQL Server 2005, but on SQL Server 2008 you can use a recursive common table expression (replacing the fixed dates below with your procedure parameters). The first part gets the first time, the second part keeps calculating the time between the last time and the end time until the difference between the times is less than 4 hours;
WITH cte AS (
SELECT DATEADD(ms,
DATEDIFF(ms, '2013-10-22 12:00:00:000',
'2013-10-24 12:00:00:000')/2,
'2013-10-22 12:00:00:000'
) a
UNION ALL
SELECT DATEADD(ms, DATEDIFF(ms,cte.a, '2013-10-24 12:00:00:000')/2, cte.a)
FROM cte
WHERE DATEDIFF(hour, cte.a, '2013-10-24 12:00:00:000') >= 4
)
SELECT * FROM cte;
EDIT: To get the tasks that have a mail time that was in the last 2 hours (ie that should generate a mail), you can use something like;
WITH cte AS (
SELECT taskid,enddate, DATEADD(s,
DATEDIFF(s, startdate, enddate)/2, startdate) tm
FROM Tasks
UNION ALL
SELECT taskid,enddate, DATEADD(ms, DATEDIFF(ms,cte.tm, enddate)/2, cte.tm)
FROM cte
WHERE DATEDIFF(hour, cte.tm, enddate) >= 4
)
SELECT taskid, tm FROM cte WHERE tm < GETDATE() AND DATEDIFF(hour, tm, GETDATE()) < 2
If the job runs at somewhat irregular intervals, you may want to truncate GETDATE()
to just hours.