为什么我不能在触发Trigger之后插入或更新有效数据?

时间:2015-03-23 02:09:57

标签: sql-server

这是我的简单测试触发事务: 首先,我设计了一个表格:

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); 

有人可以解释为什么以及如何修改我的代码?谢谢!

4 个答案:

答案 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.