7

我想从触发器调用存储过程,如何在 x 分钟后执行该存储过程?我正在寻找其他的东西WAITFOR DELAY

谢谢

4

2 回答 2

9

有一个定期运行的 SQL 代理作业并从表中提取存储过程参数 - 这些行还应指示存储过程的运行时间,因此 SQL 代理作业只会选择到期/稍微过期的行。它应该在调用存储过程后删除行或标记它们。

然后,在触发器中,只需在同一个表中插入一个新行。

希望在触发器中放入任何会以任何方式影响原始事务执行的内容 - 您绝对不希望造成任何延迟,或与同一数据库之外的任何内容进行交互。


例如,如果存储过程是

CREATE PROCEDURE DoMagic
    @Name varchar(20),
    @Thing int
AS
  ...

然后我们会创建一个表:

CREATE TABLE MagicDue (
    MagicID int IDENTITY(1,1) not null, --May not be needed if other columns uniquely identify
    Name varchar(20) not null,
    Thing int not null,
    DoMagicAt datetime not null
)

SQL 代理工作会做:

WHILE EXISTS(SELECT * from MagicDue where DoMagicAt < CURRENT_TIMESTAMP)
BEGIN
    DECLARE @Name varchar(20)
    DECLARE @Thing int
    DECLARE @MagicID int

    SELECT TOP 1 @Name = Name,@Thing = Thing,@MagicID = MagicID from MagicDue where DoMagicAt < CURRENT_TIMESTAMP

    EXEC DoMagic @Name,@Thing

    DELETE FROM MagicDue where MagicID = @MagicID
END

触发器只有:

CREATE TRIGGER Xyz ON TabY after insert
AS
    /*Do stuff, maybe calculate some values, or just a direct insert?*/
    insert into MagicDue (Name,Thing,DoMagicAt)
    select YName,YThing+1,DATEADD(minute,30,CURRENT_TIMESTAMP) from inserted

如果您在不支持代理的版本中运行,那么您可能不得不伪造它。我过去所做的是创建一个包含“可怜的人代理工作”的存储过程,例如:

CREATE PROCEDURE DoBackgroundTask
AS

     WHILE 1=1
     BEGIN
         /* Add whatever SQL you would have put in an agent job here */

         WAITFOR DELAY '00:05:00'
     END

然后,创建第二个存储过程,这次是在master数据库中,等待 30 秒,然后调用第一个过程:

CREATE PROCEDURE BootstrapBackgroundTask
AS
    WAITFOR DELAY '00:00:30'
    EXEC YourDB..DoBackgroundTask

然后,将此过程标记为启动过程,使用sp_procoption

EXEC sp_procoption N'BootstrapBackgroundTask', 'startup', 'on'

并重新启动服务 - 您现在将有一个持续运行的查询。

于 2012-06-28T07:58:01.727 回答
1

我有一种类似的情况,在使用触发器处理插入到表中的记录之前,我想确保关系表中的所有相关相关数据也都在那里。

我的解决方案是创建一个临时表,该表由第一个表上的插入触发器填充。

临时表有一个更新的标志(默认设置为 0)和一个插入get date()日期字段,以及来自主表的相关标识符。

然后,我创建了一个计划的过程来循环遍历暂存表并执行我想单独针对每条记录执行的任何过程,并在处理每条记录时更新“更新标志”。

但是,这是我有点聪明的地方,在循环过程中查找具有 . 的临时表中的记录时update flag = 0,我还添加ANDAND datediff(mi, Updated_Date, getdate())> 5. 因此,直到将记录插入临时表 5 分钟后,才会​​真正处理该记录。

于 2013-03-26T10:19:02.010 回答