在延迟一段时间后从触发器执行存储过程

Moh*_*bee 6 sql-server stored-procedures sql-server-2000 sql-server-express sql-server-2008

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

谢谢

Dam*_*ver 9

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

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

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


例如,如果存储过程是

CREATE PROCEDURE DoMagic
    @Name varchar(20),
    @Thing int
AS
  ...
Run Code Online (Sandbox Code Playgroud)

然后我们创建一个表:

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
)
Run Code Online (Sandbox Code Playgroud)

并且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
Run Code Online (Sandbox Code Playgroud)

触发器只有:

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
Run Code Online (Sandbox Code Playgroud)

如果您运行的版本不支持代理,那么您可能需要伪造它.我过去所做的是创建一个包含"穷人代理人工作"的存储过程,例如:

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
Run Code Online (Sandbox Code Playgroud)

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

CREATE PROCEDURE BootstrapBackgroundTask
AS
    WAITFOR DELAY '00:00:30'
    EXEC YourDB..DoBackgroundTask
Run Code Online (Sandbox Code Playgroud)

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

EXEC sp_procoption N'BootstrapBackgroundTask', 'startup', 'on'
Run Code Online (Sandbox Code Playgroud)

并重新启动服务 - 您现在将持续运行查询.