2013-08-07 62 views
0

我一直在尋找這一點,現在我找不到任何方式來觸發插入後發生但提交發生之前的觸發器。我需要這樣做,以便在插入信息出現問題時能夠回到角色,但也需要檢查插入的信息,以便在插入完成後進行。SQL Server:後插入預先提交觸發器

是否有觸發器來執行此操作或者任何可以重現此功能的方法?

回答

1

觸發器在提交之前被激活。在觸發器可以使用ROLLBACK如果一些檢查失敗:

CREATE TABLE dbo.Product(
    Id INT NOT NULL PRIMARY KEY, 
    Name NVARCHAR(100) NOT NULL, 
    UnitPrice NUMERIC(9,2) NOT NULL -- CHECK (UnitPrice > 0) 
); 
GO 
CREATE TRIGGER trgIU_Product_VerifyUnitPrice 
ON dbo.Product 
AFTER INSERT, UPDATE 
AS 
BEGIN 
    IF UPDATE(UnitPrice) 
    BEGIN 
     -- For simple checks you could use CHECK constraints 
     -- inserted and deleted are virtual tables store the new and the old rows (values) 
     IF EXISTS(SELECT * FROM inserted WHERE UnitPrice <= 0) 
     BEGIN 
      ROLLBACK; -- It "cancels" current transaction 
      RAISERROR('Wrong UnitPrice.',16,1); -- It notifies the caller that there is an error 
     END 
    END 
END; 
GO 

SET NOCOUNT ON; 
PRINT 'Test #1'; 
INSERT INTO dbo.Product (Id,Name,UnitPrice) 
SELECT 1 , 'PCs  ', 1200; 

PRINT 'Test #2'; 
INSERT INTO dbo.Product (Id,Name,UnitPrice) 
SELECT 2 , 'MACs  ', 2200; 

PRINT 'Test #3'; 
INSERT INTO dbo.Product (Id,Name,UnitPrice) 
SELECT 3 , 'Keyboard ', 0; 

PRINT 'Test #4'; 
INSERT INTO dbo.Product (Id,Name,UnitPrice) 
SELECT 4 , 'AAA', 111 
UNION ALL 
SELECT 5 , 'BBB', 0; 
GO 

PRINT 'Test #5'; 
BEGIN TRANSACTION; 
INSERT INTO dbo.Product (Id,Name,UnitPrice) 
SELECT 6 , 'CCC', 222 
UNION ALL 
SELECT 7 , 'DDD', 0; 
COMMIT TRANSACTION; 
GO 
SELECT @@TRANCOUNT AS [Active transactions count]; 
GO 

PRINT 'Test #6'; 
SELECT * FROM dbo.Product; 

結果:

/* 
Test #1 

Test #2 

Test #3 
Msg 50000, Level 16, State 1, Procedure trgIU_Product_VerifyUnitPrice, Line 11 
Wrong UnitPrice. 
Msg 3609, Level 16, State 1, Line 11 
The transaction ended in the trigger. The batch has been aborted. 

Test #4 
Msg 50000, Level 16, State 1, Procedure trgIU_Product_VerifyUnitPrice, Line 11 
Wrong UnitPrice. 
Msg 3609, Level 16, State 1, Line 2 
The transaction ended in the trigger. The batch has been aborted. 

Test #5 
Msg 50000, Level 16, State 1, Procedure trgIU_Product_VerifyUnitPrice, Line 11 
Wrong UnitPrice. 
Msg 3609, Level 16, State 1, Line 3 
The transaction ended in the trigger. The batch has been aborted. 
Active transactions count 
------------------------- 
0 

Test #6 
Id Name UnitPrice 
-- ---- --------- 
1 PCs 1200.00 
2 MACs 2200.00 
*/ 

參考文獻:http://technet.microsoft.com/en-us/library/ms189799.aspx

1

看到什麼documentation說關於後觸發器。

AFTER指定僅當觸發SQL語句中指定的所有操作 已成功執行時觸發DML觸發器。

您可以輕鬆編寫AFTER觸發器,但不能用它來控制事務發生之前發生的事情。可能有一個明確的交易,直到例如'手動'回滾或提交。