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

Pro*_*irl 34 mysql sql database

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

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

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

谢谢.

egg*_*yal 38

这很可能是业务逻辑,可能不属于您的数据存储层.但是,它仍然可以使用触发器来完成.

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 ...;
Run Code Online (Sandbox Code Playgroud)

请注意,这SIGNAL是在MySQL 5.5中引入的.在早期版本中,您必须执行一些导致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 ;
Run Code Online (Sandbox Code Playgroud)

但这绝对可怕的,我会做任何事情,尽可能避免它.

  • @Programmer:[`<=>`](http://dev.mysql.com/doc/en/comparison-operators.html#operator_equal-to)是`NULL`-安全等式比较运算符; "OLD"和"NEW"是触发器中可用的关键字,可在操作之前/之后提供对受影响记录值的访问 - 请参阅[触发语法](http://dev.mysql.com/doc/en/trigger-syntax. HTML); `DELIMITER`指定一个新的语句分隔符,以便将包含通常的`;`分隔符的命令视为单个语句 - 如果您愿意,可以选择除`;;`之外的字符序列. (3认同)
  • 现在有一个非传统的解决方案.我喜欢.+1请记住,虽然你在mysql中只能有一个触发器(每个表每个事件),所以如果你将来已经拥有或需要另一个触发器......你必须将它们组合成一个. (2认同)