这是我的简单测试触发事务: 首先,我设计了一个表格:
CREATE TABLE T2_Score (
UserID INT Primary key,
Months INT,
Score INT
);
然后,创建一个而不是触发器来设置限制,以确保Months的值应该在1到12之间。
CREATE TRIGGER T2_Score_Months_Restriction
ON T2_Score
INSTEAD OF UPDATE, INSERT
AS
IF ((SELECT Months FROM inserted) > 12)
BEGIN
PRINT ('Month must be between 1 and 12!')
ROLLBACK TRAN
END
但是,问题是如果触发器被触发一次,我无法插入任何有效值。 例如:
INSERT INTO T2_Score VALUES (11,15,18);
如果我尝试有效值(无警告说明,但文件将值插入表格),则插入已归档,例如:
INSERT INTO T2_Score VALUES (11,12,18);
有人可以解释为什么以及如何修改我的代码?谢谢!
答案 0 :(得分:2)
使用约束会不会更简单
?CREATE TABLE T2_Score (
UserID INT Primary key,
Months INT,
Score INT,
CONSTRAINT CHK_MONTHS_1_12 CHECK (Months BETWEEN 1 AND 12)
);
答案 1 :(得分:0)
而不是触发器在MySQL中不起作用。您可以使用BEFORE INSERT和BEFORE更新并中止操作:
CREATE TRIGGER T2_Score_Months_Restriction
ON T2_Score
BEFORE INSERT,UPDATE
AS
IF ((SELECT Months FROM inserted) > 12)
BEGIN
DECLARE msg VARCHAR(255);
IF (SomeTestToFail = "FAIL!") THEN
set msg = "Month must be between 1 and 12!";
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = msg;
END IF;
END;
答案 2 :(得分:0)
您的INSERT
将以原子方式进行调整。它将作为一个整体取得成功,否则它将作为一个整体失败。您可以通过删除inserted
中的无效值来解决这个问题,但我不推荐它。
当部分SQL语句失败时,允许SQL语句部分成功是一个非常糟糕的主意。
答案 3 :(得分:0)
该触发器永远不会插入任何行。它是一个INSTEAD OF触发器,没有任何INSERT语句。
你需要:
CREATE TRIGGER T2_Score_Months_Restriction
ON T2_Score
INSTEAD OF UPDATE, INSERT
AS
IF (SELECT MAX(Months) FROM inserted) > 12 BEGIN
PRINT ('Month must be between 1 and 12!') ;
ROLLBACK TRAN ;
END
ELSE BEGIN
INSERT INTO T2_Score SELECT * FROM inserted ;
END ;
或者也许:
CREATE TRIGGER T2_Score_Months_Restriction
ON T2_Score
INSTEAD OF UPDATE, INSERT
AS
INSERT INTO T2_Score
SELECT * FROM inserted WHERE Months BETWEEN 1 AND 12 ;
第二个版本允许部分插入。
INSERT INTO T2_Score VALUES ( 4, 4, 4 ), ( 13, 13, 13 );
-- With the first trigger, this will insert 0 rows.
-- With the second trigger, this will insert 1 row.