Trả lời

9

Có một công việc SQL Agent chạy thường xuyên và kéo lưu trữ tham số thủ tục từ một bảng - các hàng nên chỉ còn khi chạy của họ về thủ tục lưu trữ nên xảy ra , do đó, tác vụ SQL Agent sẽ chỉ chọn các hàng đến hạn/hơi quá hạn. Nó sẽ xóa các hàng hoặc đánh dấu chúng sau khi gọi thủ tục được lưu trữ.

Sau đó, trong trình kích hoạt, chỉ cần chèn hàng mới vào cùng một bảng này.

Bạn không muốn đặt bất kỳ thứ gì vào trình kích hoạt sẽ ảnh hưởng đến việc thực hiện giao dịch gốc theo bất kỳ cách nào - bạn chắc chắn không muốn gây ra bất kỳ sự chậm trễ nào hoặc tương tác với bất kỳ điều gì bên ngoài cơ sở dữ liệu.


Ví dụ, nếu các thủ tục lưu trữ là

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

Sau đó, chúng tôi muốn tạo ra một bảng:

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 
) 

Và công việc SQL Agent sẽ làm gì:

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 

Và kích hoạt sẽ chỉ có:

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 

Nếu bạn đang chạy trong một phiên bản không hỗ trợ đại lý, sau đó bạn có thể phải giả nó. Những gì tôi đã làm trong quá khứ là để tạo ra một thủ tục lưu trữ có chứa các "công ăn việc làm đại lý mans nghèo", một cái gì đó như:

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 

Sau đó, tạo một thủ tục lưu trữ thứ hai, lần này trong cơ sở dữ liệu master, mà đợi 30 giây và sau đó gọi các thủ tục đầu tiên:

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

và sau đó, đánh dấu thủ tục này như một thủ tục khởi động, sử dụng sp_procoption:

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

Và khởi động lại dịch vụ - bây giờ bạn sẽ có một truy vấn chạy liên tục.

+0

Xin lỗi nếu quên thêm thẻ sql-express. –

+1

@MohammedRabee - Đã xảy ra sự cố với việc gắn thẻ của bạn sau đó - Không có SQL Server 2000 Express. Có MSDE, nhưng ấn bản đầu tiên là 2005. Bạn có thể sửa không? –

+0

Tôi muốn điều này làm việc trên sql-server2000 và sql-server2008express –

1

Tôi đã có một tình huống tương tự, trước khi tôi xử lý các bản ghi được chèn vào bảng bằng trình kích hoạt, tôi muốn đảm bảo tất cả các dữ liệu liên quan có liên quan trong bảng quan hệ cũng có.

Giải pháp của tôi là tạo bảng cào được điền bằng trình kích hoạt chèn trên bảng đầu tiên.

Bảng cào có cờ được cập nhật, (mặc định được đặt thành 0) và trường nhập ngày get date() và số nhận dạng có liên quan từ bảng chính.Sau đó tôi đã tạo một quy trình được lên lịch để lặp qua bảng cào và thực hiện bất kỳ quy trình nào tôi muốn thực hiện đối với từng bản ghi riêng lẻ và cập nhật 'cờ cập nhật' khi mỗi bản ghi được xử lý.

NHƯNG, đây là nơi tôi khá thông minh, trong vòng lặp quá trình tìm kiếm bản ghi trong bảng cào có số update flag = 0, tôi cũng thêm mệnh đề AND của AND datediff(mi, Updated_Date, getdate())> 5. Vì vậy, bản ghi sẽ không thực sự được xử lý cho đến 5 phút SAU KHI nó được đưa vào bảng cào.

Các vấn đề liên quan