我的数据库中有一个名为Tasks
的表。
该表中的每条记录都有2个字段:StartDate
,EndDate
我需要创建递归存储过程,在这些日期的中间发送邮件
例如:
开始时间为2013-10-22 12:00:00:000
结束是2013-10-24 12:00:00:000
我能做到:
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')
然后检查现在是否大于该日期,如果是,那么我可以发送邮件。
但是我需要递归地做到这一点:第一个主要必须是中间发送,第二个是1/4,第三个是1/8等,最后是剩下2个小时。
我的第一个想法是在我的表中添加列并在其中存储最后一个main的日期,但我想避免修改表。
我认为递归选择会更好,但欢迎任何有关如何解决的想法:)
编辑:我的样本小提琴:http://sqlfiddle.com/#!3/25d0d/1
我的例子:
任务从2013-10-22 8:00开始,到2013-10-22 21:00结束
程序从2013-10-22 10:00开始 第一条记录发送时间为14:30,所以无需发送
程序从2013-10-22 12:00开始 第一条记录发送时间为14:30,所以无需发送
程序从2013-10-22 14:00开始 第一条记录发送时间为14:30,所以无需发送
程序从2013-10-22 16:00开始 第一条记录发送时间为14:30,因此发送有关该任务的邮件
下一条消息应该在17:45左右发送
程序开始于2013-10-22 18:00
第一条记录发送时间为17:45,因此发送有关该任务的邮件
下一条消息应该在19:22左右发送
程序从2013-10-22 20:00开始
第一条记录的发送时间为19:22所以应该发送邮件,
但是因为从19:22到21:00不到2个小时就不需要邮件了
答案 0 :(得分:1)
无法在SQL Server 2005上进行测试,但在SQL Server 2008上,您可以使用递归公用表表达式(使用过程参数替换下面的固定日期)。第一部分是第一部分,第二部分是继续计算最后一次和结束时间之间的时间,直到时间差小于4小时;
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;
编辑:要获得具有过去2小时内邮件时间的任务(即应生成邮件),您可以使用类似的内容;
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
如果作业以不规则的间隔运行,您可能希望将GETDATE()
截断为几小时。