1

如果 if 条件失败,如何停止交易?

如果为真,我希望此事务停止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'; 

它会引发错误,但也会进行更新。

谢谢你。

4

3 回答 3

2

我相信您可以使用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
于 2013-04-28T20:00:56.353 回答
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:[SMALL]DATE[TIME][2] 常量应遵循 ISO8601 规则:yyyymmdd,yyyymmdd hh:mm:ssyyyy-mm-dd, yyyy-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 和 dela 列,则会产生误导。

注意 3:RAISERROR 语句的严重级别应该是 16 而不是 1。严重级别等于 1 的 RAISERROR 语句与 PRINT 语句非常相似。

于 2013-04-28T20:02:41.433 回答
1

默认情况下,事务是自动提交的,但您可以SET IMPLICIT_TRANSACTIONS ON;,然后在查询结束时您可以COMMIT T1;看看这个

于 2013-04-28T19:49:16.260 回答