2013-05-19 38 views
3

我想让一个Mysql表中的行不可变,一旦它们插入,我不希望它有可能改变它们。我怎样才能做到这一点?使行不可变,并允许插入

(理想情况下,如果尝试进行更改,请返回适当的错误消息)。

我没有授予特权,所以我想了解如何编写BEFORE UPDATE触发器引发错误(使用信号或发出总是失败的语句)。 我使用mysql5。

回答

3

一个非常简单的触发器应该这样做;

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(现有的行)将会使更新失败。

+0

谢谢,我会尝试,“olle”是表名正确吗? – ol30cean0

+0

@ user2105729是的,抱歉的命名,将修复:) –

+0

我试图让我收到#1064 - 你的SQL语法错误;请检查与您的MySQL服务器版本相对应的手册,以便在第3行附近'SQLSTATE'45000'SET MESSAGE_TEXT ='Update not allowed!''使用正确的语法 – ol30cean0

0

如果您使用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; 

但您必须手动插入到此新表中。