2017-12-02 264 views
1

我有一个包含许多列的表,并且我试图在更新之前对特定列实施一个触发器,以确保只能根据特定列更改该特定列的值到1到2到3的特定转换。BEFORE UPDATE触发器阻止所有更新

例如,如果列中的值为1,则如果尝试将其更改为1到3,则该列上的更新将被拒绝,但如果它从1变为2则接受。

下面的代码有效,但是它当前拒绝所有不符合该更新的更新。例如,如果我尝试更新该表中不同列的行,即使我没有以任何方式更改值列,我的更新也会被拒绝。

DELIMITER // 
CREATE TRIGGER transition BEFORE UPDATE ON tbl 
FOR EACH ROW 
BEGIN 
IF (OLD.value = 1 AND NEW.value != 2) 
OR (OLD.value = 2 AND NEW.value != 3) 
SIGNAL SQLSTATE '45000' 
SET MESSAGE_TEXT = 'Incorrect transition of values'; 
END IF; 
END // 
DELIMITER; 

我该如何解决这个问题,以便我可以建立转换一致性,同时仍然能够更新其他列?

我使用mariadb 5.5.50。

非常感谢!

回答

1

这将允许值保持不变:

CREATE TRIGGER transition BEFORE UPDATE ON tbl 
FOR EACH ROW 
BEGIN 
    IF (OLD.value = 1 AND NEW.value NOT IN (1, 2)) 
    OR (OLD.value = 2 AND NEW.value NOT IN (2, 3)) 
    THEN 
    SIGNAL SQLSTATE '45000' 
    SET MESSAGE_TEXT = 'Incorrect transition of values'; 
    END IF; 
END// 

我测试了这一点:

mysql> insert into tbl set value=1, other=11; 
Query OK, 1 row affected (0.00 sec) 

mysql> update tbl set other=22; 
Query OK, 1 row affected (0.00 sec) 
Rows matched: 1 Changed: 1 Warnings: 0 

mysql> update tbl set value=1, other=33; 
Query OK, 1 row affected (0.01 sec) 
Rows matched: 1 Changed: 1 Warnings: 0 

mysql> update tbl set value=2, other=44; 
Query OK, 1 row affected (0.00 sec) 
Rows matched: 1 Changed: 1 Warnings: 0 

mysql> update tbl set value=1, other=55; 
ERROR 1644 (45000): Incorrect transition of values 

mysql> update tbl set value=2, other=66; 
Query OK, 1 row affected (0.00 sec) 
Rows matched: 1 Changed: 1 Warnings: 0 

mysql> update tbl set value=2, other=77; 
Query OK, 1 row affected (0.00 sec) 
Rows matched: 1 Changed: 1 Warnings: 0 

mysql> update tbl set value=3, other=88; 
Query OK, 1 row affected (0.00 sec) 
Rows matched: 1 Changed: 1 Warnings: 0 

但之后的值是3,会发生什么?它可以变成任何东西,还是必须保持3?您可能需要另一个术语来测试。

+0

感谢您的回答,但我希望能够从1 - > 2或2 - > 3更改该特定列中的值,但拒绝任何不符合该转换的更改(例如,1 - > 3 [UPDATE tbl SET value = 3 WHERE value = 1,应该被拒绝)。目前,我的触发器管理着这一点,但问题是我无法更新表格中的任何其他列,即使它们没有更改“值”中的任何内容。我怎样才能解决这个问题? – Olivier

+0

我提供的解决方案符合您的需求。我编辑了我的答案,上面包含了一个测试演示。 –

+0

我的歉意,我误解了。完美的作品,谢谢! – Olivier