我们利用SSIS(SQL / BIDS 2008)每天生成近1000个报告。在SQL Agent中,在交错的计划上安排相同的包5次。
SSIS查询Report
表,如果报告在指定日期尚未运行(请检查ReportLog
)且该报告当前未运行(请检查WorkQueue
)第一个(顶部)报告被选中并运行。
该查询是有效的:
SELECT TOP 1 R.ReportID
FROM Report R
LEFT JOIN ReportLog L ON R.ReportID=L.ReportID AND L.RunDate >= CONVERT(DATE,GETDATE())
LEFT JOIN WorkQueue Q ON R.ReportID=Q.ReportID
WHERE R.Active=1
AND L.ReportID IS NULL
AND Q.ReportID IS NULL
SSIS包在选择此TOP 1 ReportID
(存储在SSIS变量中)后,将ReportID
插入WorkQueue
,因此包的其他任何实例都不会尝试使用ReportID
{1}}。插入在选择后的下一步中发生。
大多数时候,大多数时候,这都很好。但是,每隔两个SSIS包最终会在(几毫秒内)完全相同的时间内运行,并且两者都返回相同的TOP 1 ReportID
,因为它们都执行相同的过程,并且操纵相同的程序基础数据。
现在,我们正在考虑实现一个父SSIS包,它执行select
并将ReportID
放入一个“缓冲区”表以及5个子包之一的Job#拿起(而不是孩子们所有人都做自己的select top 1
),但这似乎非常hacky。
我们考虑的另一个选项是instead of insert
表上的WorkQueue
触发器,这会在重复插入时引发错误。
我想知道SSIS中是否还有其他方法可以在没有太多重新设计的情况下防止出现这种情况。
答案 0 :(得分:2)
如何避免触发并使用OUTPUT子句?
INSERT INTO
WorkQueue
OUTPUT Inserted.ReportID
SELECT TOP 1 R.ReportID
FROM Report R
LEFT JOIN ReportLog L ON R.ReportID=L.ReportID AND L.RunDate >= CONVERT(DATE,GETDATE())
LEFT JOIN WorkQueue Q ON R.ReportID=Q.ReportID
WHERE R.Active=1
AND L.ReportID IS NULL
AND Q.ReportID IS NULL;
这应允许您将行行弹出到workQueue表中,以便为当前进程声明它,同时检索要使用的SSIS值。