我正在运行 SQL Server 2008 R2,并且我有一个触发器,它插入到一个表中,然后 asql 代理作业每 10 秒启动一次以运行 sp 以发送电子邮件通知。我遇到的问题是,当大量插入同时发生时,通知可能会挂起并且在插入发生后几分钟(有时长达一个小时)内不会发送出去。 tb_BatchEmail 只接收一次插入几个(2-3 个),是 Orders 表可以同时进行几十个插入。所以我的问题是 - 这是设置这种类型的触发器的最佳方法,还是有更好的方法更有效并且在同时发生大量表插入时不会落后?
这是触发器:
ALTER TRIGGER [dbo].[VoceraOeOrders] ON [dbo].[Orders]
AFTER INSERT
AS
BEGIN
SET NOCOUNT ON;
INSERT INTO dbo.tb_BatchEmail (
BatchEmailID
,[To]
,Body
,[Subject]
,[Profile]
,OrderID
,OrderDateTime
,SentDateTime
)
SELECT '0'
,'some_email'
,CASE
WHEN RoomTreatmentID IS NULL
THEN 'No Room#'
ELSE RoomTreatmentID
END + '-' + OrderedProcedureName
,CASE
WHEN Category = 'US'
THEN 'Stat Ultra Sound'
WHEN Category = 'NUC'
THEN 'Stat Nuclear'
WHEN Category = 'ECHO'
THEN 'Stat Echo'
WHEN Category = 'CT'
THEN 'Stat C T'
WHEN Category = 'MRI'
THEN 'Stat M R I'
WHEN Category = 'XRAY'
THEN 'Stat Xray'
ELSE 'Stat Order Alerts'
END
,'Alert'
,OrderID
,OrderDateTime
,NULL
FROM inserted i
INNER JOIN dbo.Patients pat
ON pat.VisitID = i.VisitID
AND pat.SourceID = i.SourceID
WHERE Priority = 'STAT'
AND Category IN ('CT', 'MRI', 'XRAY', 'US', 'NUC', 'ECHO')
AND CurrentLocationID = 'ED'
END
这是设置为通过服务器代理作业每 10 秒启动一次的 sp:
ALTER PROCEDURE [dbo].[sp_SendVoceraMail]
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
DECLARE @Id INT
DECLARE @To VARCHAR(250)
DECLARE @Body VARCHAR(250)
DECLARE @Subject VARCHAR(50)
DECLARE @ProfileName VARCHAR(20)
WHILE (
SELECT count(*)
FROM tb_BatchEmail
WHERE BatchEmailID = 0
) > 0
BEGIN
SELECT TOP 1 @Id = Id
,@To = [To]
,@Body = Body
,@Subject = [Subject]
,@ProfileName = [Profile]
FROM tb_BatchEmail
WHERE BatchEmailID = 0
EXEC msdb.dbo.sp_send_dbmail @recipients = @To
,@body = @Body
,@subject = @Subject
,@profile_name = @ProfileName
UPDATE tb_BatchEmail
SET BatchEmailID = 1
,SentDateTime = GETDATE()
WHERE Id = @Id
END
END