如何将MySQL行设置为READ-ONLY?

时间:2012-05-08 16:09:17

标签: mysql sql database

我在表中有一行我不想改变(永远)。

是否可以将MySQL行设置为READ-ONLY,以便无法以任何方式更新?如果是这样,怎么样?

如果没有,是否可以在该行的一列中设置永久值,以便不能更改?如果是这样,怎么样?

感谢。

1 个答案:

答案 0 :(得分:36)

这可能是业务逻辑,可能不属于您的数据存储层。但是,它仍然可以使用triggers完成。

如果要更新“锁定”记录,您可以创建一个引发错误的BEFORE UPDATE触发器;由于在执行操作之前发生错误,MySQL将停止继续操作。如果您还想阻止删除记录,则需要创建类似的触发器BEFORE DELETE

要确定记录是否已“锁定”,您可以创建一个布尔locked列:

ALTER TABLE my_table ADD COLUMN locked BOOLEAN NOT NULL DEFAULT FALSE;

DELIMITER ;;

CREATE TRIGGER foo_upd BEFORE UPDATE ON my_table FOR EACH ROW
IF OLD.locked THEN
  SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Cannot update locked record';
END IF;;

CREATE TRIGGER foo_del BEFORE DELETE ON my_table FOR EACH ROW
IF OLD.locked THEN
  SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Cannot delete locked record';
END IF;;

DELIMITER ;

UPDATE my_table SET locked = TRUE WHERE ...;

请注意,在MySQL 5.5中引入了SIGNAL。在早期版本中,您必须执行一些导致MySQL引发错误的错误操作:我经常调用一个不存在的过程,例如与CALL raise_error;


  

我无法在此表上创建其他列,但该行在其中一列中具有唯一ID,那么我该如何为该场景执行此操作?

同样,如果您绝对必须将此逻辑放在存储层中 - 并且无法通过PK以外的任何方式识别锁定的记录 - 您可以硬编码测试你的触发器;例如,使用id_column = 1234

“锁定”记录
DELIMITER ;;

CREATE TRIGGER foo_upd BEFORE UPDATE ON my_table FOR EACH ROW
IF OLD.id_column <=> 1234 THEN
  SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Cannot update locked record';
END IF;;

CREATE TRIGGER foo_del BEFORE DELETE ON my_table FOR EACH ROW
IF OLD.id_column <=> 1234 THEN
  SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Cannot delete locked record';
END IF;;

DELIMITER ;

但这绝对可怕而且我会做几乎所有以尽可能避免它。