如果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';
它会引发错误,但也会进行更新。
谢谢。
答案 0 :(得分:2)
您必须知道SQL Server DML触发器基于始终设置而不是基于行。因此,inserted
和deleted
表可能包含更多行,而不仅仅是一行。
如果要在(@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:ss
或yyyy-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语句非常相似。
答案 1 :(得分:1)
默认情况下,交易是自动提交的,但您可以SET IMPLICIT_TRANSACTIONS ON;
然后在查询结束时COMMIT T1;
查看this。
答案 2 :(得分: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