使行不可变,并允许插入
问题描述:
我想让一个Mysql表中的行不可变,一旦它们插入,我不希望它有可能改变它们。我怎样才能做到这一点?使行不可变,并允许插入
(理想情况下,如果尝试进行更改,请返回适当的错误消息)。
我没有授予特权,所以我想了解如何编写BEFORE UPDATE触发器引发错误(使用信号或发出总是失败的语句)。 我使用mysql5。
答
一个非常简单的触发器应该这样做;
CREATE TRIGGER stop_update BEFORE UPDATE ON table1
FOR EACH ROW
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Update not allowed!'
//
An SQLfiddle to test with。您可以添加更新以进行测试。
当然,您可能也想为DELETE
做同样的事情。
编辑:如果你使用的是比5.5更低的MySQL版本添加信号,你可以通过(不完全干净地)写入来限制写入而不是故意造成错误;
CREATE TRIGGER stop_update BEFORE UPDATE ON table1
FOR EACH ROW
UPDATE UPDATE_OF_TABLE1_IS_NOT_ALLOWED SET value='Update not allowed!'
//
Another SQLfiddle。无法在DDL中添加错误并使用SQLfiddle保存它,因此在左侧窗口中将更新的ID更改为1(现有的行)将会使更新失败。
答
如果您使用InnoDB,则不使用触发器的另一种解决方案。
创建另一个重复的表。 新列中的列应该有外键(因此这个解决方案中的innodb要求)指向所讨论的原始表的列。
为每个键设置“ON UPDATE RESTRICT”之类的限制。以下代码为一列:
CREATE TABLE original (
....
immutable_column ...
INDEX index1(immutable_column)
....
) ENGINE=INNODB;
CREATE TABLE restricter (
.....
col1,
INDEX index2(col1),
FOREIGN KEY (col1) REFERENCES original (immutable_colum) ON UPDATE RESTRICT ON DELETE CASCADE
) ENGINE=INNODB;
但您必须手动插入到此新表中。
谢谢,我会尝试,“olle”是表名正确吗? – ol30cean0
@ user2105729是的,抱歉的命名,将修复:) –
我试图让我收到#1064 - 你的SQL语法错误;请检查与您的MySQL服务器版本相对应的手册,以便在第3行附近'SQLSTATE'45000'SET MESSAGE_TEXT ='Update not allowed!''使用正确的语法 – ol30cean0