2013-04-28 34 views
0

如何在if條件失敗時停止事務?如何在SQL Server 2008中停止事務?

如果IF (@dela = '01-01-2013')爲真,我希望此交易停止,但相反會引發錯誤並執行Update執行。

CREATE TRIGGER TR_AdaugareModificareOfertaSpeciala 
ON OferteSpeciale 
FOR UPDATE, INSERT 
AS 
BEGIN TRAN T1; 
DECLARE @dela DATETIME; 
SET @dela = (SELECT dela FROM INSERTED); 

IF (UPDATE(codP) OR UPDATE(codM) OR UPDATE(dela)) 
BEGIN 
RAISERROR('Nu se poate modifica cheia primara.', 1, 1); 
ROLLBACK TRAN T1; 
END 

SAVE TRANSACTION T1; 
IF (@dela = '01-01-2013') 
BEGIN 
RAISERROR('Data nu este corecta.', 1, 1); 
ROLLBACK TRAN T1; 
END 

例子dela = '01-01-2013':

UPDATE OferteSpeciale SET pret = 23.69 where codP = 'P1' and codM = 'M1'; 

它引發錯誤,但也使得更新。

謝謝。

回答

2

你必須知道,SQL Server的DML觸發器是總是一套基於而不是基於行的。所以,inserteddeleted表可能包含更多行,而不只是一行。

如果要取消更新/插入語句時(@dela = '01-01-2013')那麼你可以使用此條件:

IF EXISTS(SELECT * FROM inserted WHERE dela = '20130101') 
BEGIN 
ROLLBACK; 
RAISERROR('The starting date is wrong', 16, 1); 
END 

注1:[小]日期[時間] [2]常量應遵循ISO8601規則:yyyymmddyyyymmdd hh:mm:ssyyyy-mm-ddyyyy-mm-ddThh:mm:ss

注2:從

IF (UPDATE(codP) OR UPDATE(codM) OR UPDATE(dela)) 
BEGIN 
RAISERROR('Nu se poate modifica cheia primara.', 1, 1); 
ROLLBACK TRAN T1; 
END 

錯誤消息是誤導性的,如果PK不包含CODP,CODM和德拉列。

注意3:RAISERROR語句的嚴重級別應該爲16而不是1。嚴重級別等於1的RAISERROR語句與PRINT語句非常相似。

1

默認情況下,交易是自動提交的,但您可以SET IMPLICIT_TRANSACTIONS ON;,然後在查詢結束後您可以COMMIT T1;查看this

1

我相信你可以用INSTEAD OF UPDATE觸發器來做到這一點。

CREATE TRIGGER TR_AdaugareModificareOfertaSpeciala 
ON OferteSpeciale 
INSTEAD OF UPDATE 
AS 

DECLARE @dela DATETIME; 
SET @dela = (SELECT dela FROM INSERTED); 

IF (UPDATE(codP) OR UPDATE(codM) OR UPDATE(dela)) BEGIN 
    RAISERROR('Nu se poate modifica cheia primara.', 1, 1); 
END 

ELSE IF (@dela = '01-01-2013') BEGIN 
    RAISERROR('Data nu este corecta.', 1, 1); 
END 
ELSE BEGIN 
    UPDATE o SET dela = i.dela, codm = i.codm, codp = i.codp, pret = i.pret-- add rest of columns here 
    FROM OferteSpeciale o 
     JOIN Inserted i ON o.[Primarykey] = i.[Primarykey] 
END