回答

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 

如果你在不支持代理的版本上運行,那麼你可能有捏造事實。我已經在過去做的是創建一個包含「窮男人的代理工作」的存儲過程,是這樣的:在master數據庫

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 

然後,創建第二個存儲過程,這個時間,這等待30秒,然後調用第一程序:

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

然後,標記這個過程作爲一個啓動程序,使用sp_procoption

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

並重新啓動服務 - 您現在將擁有連續運行的查詢。

+0

對不起,如果忘記添加sql-express標籤。 –

+1

@MohammedRabee - 您的標記出現問題 - 沒有SQL Server 2000 Express。有MSDE,但第一個快速版是2005年。請問你能改正嗎? –

+0

我想要這個在sql-server2000和sql-server2008express上運行 –

1

我曾經有過類似的情況,在處理插入到表中的記錄之前,我想確保關係表中的所有相關數據都在那裏。

我的解決方案是創建一個由第一個表上的插入觸發器填充的臨時表。

臨時表具有更新的標誌(默認設置爲0)和插入日期字段以及主表中的相關標識符。

然後,我創建了一個計劃進程,循環使用臨時表並執行我想要針對每個記錄單獨執行的任何進程,並在每個記錄處理完畢後更新'更新標誌'。

但是,這裏是我有點聰明,在循環過程中尋找具有update flag = 0的劃痕表中的記錄,我還添加了AND datediff(mi, Updated_Date, getdate())> 5AND子句。因此,記錄在插入臨時表後5分鐘後纔會真正處理。