如何通过 SQL Server 触发器运行报表服务器订阅,而不会对订阅表造成潜在的"瓶颈"?



我们使用SSRS报告来查看数据。我们有与基于SQL的报表关联的订阅触发此触发器更新订阅表并动态更改正在将电子邮件发送到。但是,如果触发器在4秒内执行两次,则可以正常工作然后最后一个电子邮件收件人接收第一个订阅的报告和第二个。

问题是,两个不同的电子邮件收件人如何获得他们自己订阅的报告如果触发器在4秒内执行了两次?

4秒后,第一个收件人收到他的电子邮件,第二个收件人收到了他的电子邮件,一切都很好。

似乎存在一个瓶颈,即多个用户可能会更新订阅表中的一行,这可能会导致潜在的问题。

是否有一种方法可以使用sql脚本创建订阅并将参数传递给报告的存储过程服务器正在使用创建新订阅还是计划订阅?

我的代码粘贴在下面,显示一旦表(EmployeeTimeSheets)中的值更新,就会执行一个触发器订阅的参数部分的ID(员工)。

是否有一种方法可以在sql server中动态构建报表服务器订阅?任何帮助都将不胜感激。

declare @WkEnd nvarchar(30);
declare @Employee nvarchar(50);
declare @UserName nvarchar(30);
declare @TimeStamp datetime;
declare @Title nvarchar(30);
declare @CompleteTS nvarchar(15);

                                    /* If no email is sent to the email afer testing this trigger then that means its past 2pm on Monday.*/
IF (UPDATE(SelfReport))
    BEGIN

                set @WkEnd=(Select distinct i.[WkEnd] FROM  inserted i INNER JOIN deleted AS d ON i.EmpId = d.EmpId)
                set @Employee=(Select distinct e.[Employee] FROM  inserted i inner join deleted d on i.empid=d.empid inner join employees e on i.empid=e.rowid)
                set @UserName=(Select distinct e.[UserName] FROM  inserted i inner join deleted d on i.empid=d.empid inner join employees e on i.empid=e.rowid)
                set @Title=(Select distinct e.[Title] FROM  inserted i inner join deleted d on i.empid=d.empid inner join employees e on i.empid=e.rowid)

                update ReportServer.dbo.Subscriptions
                    set [Parameters]='<ParameterValues>
                                            <ParameterValue><Name>WeekEnding</Name><Value>'+@WkEnd+'</Value></ParameterValue>
                                            <ParameterValue><Name>SelecDepartment</Name><Value>'+@Title+'</Value></ParameterValue>
                                            <ParameterValue><Name>SelectEmployee</Name><Value>'+@Employee+'</Value></ParameterValue></ParameterValues>',


                     [ExtensionSettings]= '<ParameterValues>
                                                <ParameterValue><Name>TO</Name><Value>'+@UserName+'@processsolutions.com</Value></ParameterValue>
                                                <ParameterValue><Name>IncludeReport</Name><Value>True</Value></ParameterValue>
                                                <ParameterValue><Name>RenderFormat</Name><Value>PDF</Value></ParameterValue>
                                                <ParameterValue><Name>Subject</Name><Value>Completed TimeSheet From '+@Employee+'</Value></ParameterValue>
                                                <ParameterValue><Name>IncludeLink</Name><Value>False</Value></ParameterValue>
                                                <ParameterValue><Name>Priority</Name><Value>NORMAL</Value></ParameterValue>
                                                <ParameterValue><Name>Comment</Name><Value>TimeSheet Completion: ' +@Employee+ ' ' +@WkEnd+ '</Value></ParameterValue>
                                           </ParameterValues>'  
                    where SubscriptionID='530f3da4-a6b5-4594-aa6b-3bfd638600d3'
                EXEC ReportServer.dbo.AddEvent @EventType='TimedSubscription', 
                                               @EventData='530f3da4-a6b5-4594-aa6b-3bfd638600d3'
END

这可能看起来有点全面,但它将避免瓶颈和并发问题:

不要让您的触发器直接更新订阅表。

相反,将触发器INSERT插入到队列表中,其中包含更新订阅表所需的任何信息。

有一个作业可以根据需要随时运行,从队列中的记录更新订阅表,然后将这些记录标记为已完成,这样它们就不会一次又一次地完成。

这避免了并发性和瓶颈,因为如果作业当前正在运行,它就无法启动,因此不能像使用触发器那样,让作业的两个实例同时尝试更新订阅表。

当然,另一种解决方案是培训创建订阅的人员正确执行订阅,而不需要触发器来帮助他们填写参数值。这就是我们在这里所做的。:)

最新更新