我一直在尋找這一點,現在我找不到任何方式來觸發插入後發生但提交發生之前的觸發器。我需要這樣做,以便在插入信息出現問題時能夠回到角色,但也需要檢查插入的信息,以便在插入完成後進行。SQL Server:後插入預先提交觸發器
是否有觸發器來執行此操作或者任何可以重現此功能的方法?
我一直在尋找這一點,現在我找不到任何方式來觸發插入後發生但提交發生之前的觸發器。我需要這樣做,以便在插入信息出現問題時能夠回到角色,但也需要檢查插入的信息,以便在插入完成後進行。SQL Server:後插入預先提交觸發器
是否有觸發器來執行此操作或者任何可以重現此功能的方法?
觸發器在提交之前被激活。在觸發器可以使用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
看到什麼documentation說關於後觸發器。
AFTER指定僅當觸發SQL語句中指定的所有操作 已成功執行時觸發DML觸發器。
您可以輕鬆編寫AFTER觸發器,但不能用它來控制事務發生之前發生的事情。可能有一個明確的交易,直到例如'手動'回滾或提交。